Composite模式带给我的只有Array有什么优势?

Edw*_*ard 6 php design-patterns

我最近正在研究树结构,多个节点,多个可增加的级别以及print()方法.起初,我认为它应该是一个复合词,然后我写下了一些可能的设计和代码:

替代文字

$struc = new Node(‘name0’, ‘id0’, ‘desc0’);
$node1 = new Node(‘node1’, ‘id1’, ‘desc1’);
$node2 = new Node(‘node2’, ‘id2’, ‘desc2’);
$node3 = new Node(‘node3’, ‘id3’, ‘desc3’);
$leaf1 = new Leaf(‘leaf1’, ‘ld1’, ‘lesc1’);
$leaf2 = new Leaf(‘leaf2’, ‘ld2’, ‘lesc2’);
$leaf3 = new Leaf(‘leaf3’, ‘ld3’, ‘lesc3’);
$leaf4 = new Leaf(‘leaf4’, ‘ld4’, ‘lesc4’);

$struc.add($node1);
$struc.add($node3);

$node1.add($leaf1);
$node1.add($leaf2);
$node1.add($node2);

$node2.add($leaf3);    
$node3.add($leaf4);
Run Code Online (Sandbox Code Playgroud)

看起来不错,我认为并开始编码,print()方法可能会遵循Iterator模式.但在编码过程中,我觉得这些简单的节点太复杂了吗?而且我必须实例化很多具体的类(超过50多个,并且不断增加).然后我通过使用数组停止并思考一个简单的类似方法:

-- Structure Class --
//To be more readable and clear, array here could be
//divided to 3 arrays(root/nodes/leafs), then connect
//in a similar way Composite does.
$struc = array('name0', 'id0', 'desc0',

           'children'=>array(

               array('node1', 'id1', 'desc1',
                  'children' => array(
                     array('leaf1', 'ld1', 'lesc1'),
                     array('leaf2', 'ld2', 'lesc2'),
                     array('node2', 'id2', 'desc2',
                        'children'=>array(array('leaf3', 'ld3', 'lesc3'))
                     )
                  )
               ),

               array('node3', 'id3', 'desc3',
                  'children' => array(array('leaf4', 'ld4', 'lesc4'))
               )
           )
);

function print($node = $this->struct) {
    ...
    if(isset($node['children'])) $this->print($node['children']);
    ...
}
Run Code Online (Sandbox Code Playgroud)

这两个设计看起来非常相似,现在我有点困惑,复合模式的价值是什么,我是否错过了这种模式的重要内容?

dfa*_*dfa 7

复合的价值在于你交易一些复杂性,因为它不能破坏封装.

在您的阵列版本中,您正在破坏封装,因为您正在测试节点是否不是叶子:

if(isset($node['children'])) $this->print($node['children']);
Run Code Online (Sandbox Code Playgroud)

用复合材料你可以说:

print();
Run Code Online (Sandbox Code Playgroud)

然后运行时多态将调用正确的方法.在这种情况下(我不是PHP程序员,所以让我使用类似Java的语法):

class Node {

   void print() {
       for (child in children) {
          child.print();
       } 
   }

   ...
}

class Leaf {

   void print() {
       // print it! 
   }
}
Run Code Online (Sandbox Code Playgroud)

与普通数组相比的另一个优点是您隐藏了实现细节(数据结构等)


Mic*_*rdt 6

复合模式的要点是能够将对象集合视为单个对象(例如,用于显示它或将其写入文件).当你自己写"print()方法可能会跟随Iterator模式" - 好吧,复合模式的要点是你可以调用print()而不必担心你是打印单个Component还是必须迭代通过整个树.

但是看起来你一般都不清楚面向对象编程,因为你正在考虑使用嵌套数组.使用对象而不是散列(PHP数组是)的一切都是类型安全的,这使得调试和维护程序变得更加容易.