PHP类设计选择

时间:2012-12-05 15:43:17

标签: php oop

我有一个类,用于生成嵌套的无序html列表。

class cTree {    

function cTree(){
}

public function getTree($id = NULL ){
}

private function addSubNode($iParentId, $iLevel){
}

其中addSubnode是一个递归函数,可以正确嵌套。

现在,我希望在我的网站上有两个导航菜单。两个无序列表,但具有不同的标记。

我认为,有3种选择:

  1. 将一个额外的变量传递给getTree()和addSubNode(),然后使用if / else构造。我不喜欢它,因为它不可维护。

  2. 在课堂上添加两个额外的功能,所以我会有例如getTopTree()/ getFooterTree和addTopSubNode()/ addFooterSubNode();

  3. 创建两个新类(类cTopMenu扩展cTree /类cFooterMenu扩展cTree)并编辑getTree / addSubNode。

  4. 如上所述,我不喜欢第一种选择但不确定第二种和第三种选择。什么是最好的设计选择?

    额外的例子,使情况更加清晰。它与上面不一样,但绝对可比。我有一棵用于导航的树:

    <ul>
      <li><a href="/x">Item 1 </a></li>
      <li><a href="/x">Item 2 </a></li>
      <li><a href="/x">Item 3 </a></li>
    </ul>
    

    然后我有另一个,有行政选项:

    <form method="post">
     <ul>
       <li>
           <input type="text" value="Item 1" />
           <input type="checkbox" value="1" id="visible_1" name="visible[]"> 
           <label for="visible_1">&nbsp;visible</label>           
       </li>
       <li>
           <input type="text" value="Item 2" />
           <input type="checkbox" value="1" id="visible_2" name="visible[]"> 
           <label for="visible_2">&nbsp;visible</label>           
       </li>
       <li>
           <input type="text" value="Item 3" />
           <input type="checkbox" value="1" id="visible_3" name="visible[]"> 
           <label for="visible_3">&nbsp;visible</label>           
       </li>
     </ul>
    </form>
    

    基本上它是同一棵树。现在我扩展了基本的树类,替换了getTree()和addSubNode()函数。

1 个答案:

答案 0 :(得分:0)

如果你能告诉我们两个预期的标记是什么以便建议一种方法,那将是非常有帮助的。说过我可以试试部分答案:

  • 正如你所说,第一个选项似乎不是一个好方法,因为这决定了在客户端上做什么的责任(即if / then / else部分)。这导致在许多地方重复该声明,这会导致测试和可维护性问题。
  • 我在第二种方法中看到的问题是,如果你这样做,cTree的一个实例将不会代表树,而是某种树的函数集合。因此,您将使用一些OO结构,但您不会遵守OO范例。另外,请考虑如果您以后决定使用新类型的树(例如侧边栏树),则应添加新的函数集(getSideTree() / addSideSubNode()),这也不会扩展。

问题恕我直言,如果您应该通过为每个案例创建一个特定的子类来处理这种情况,或者它们只是两个与另一个对象协作以获得所需输出的cTree个实例。正如我之前所说,如果不知道两个预期的产出,很难说清楚。

修改 根据新信息,我猜两种方法(子类化或组合)都是有效的:

  • 子类。我会有一个抽象类(cTree)除了渲染节点外,它可以完成所有操作。执行此操作的方法将是抽象的,具体的子类(topTreefooterTree)将负责处理此问题。您可能需要查看模板method pattern
  • 组合物。在这里,您只有一个负责渲染树结构的树类,并将节点渲染委托给另一个对象。另一个对象将在单独的层次结构中建模(例如,带有treeNodetopNode的抽象类footerNode。我喜欢这个,因为它清楚地表明树之间不同的不是它们的结构,而是节点。

正如您所看到的,第二个选项是将子类中的重写方法实现转换为多态对象的层次结构。使用哪个选项取决于渲染过程的复杂程度和个人品味。

HTH