2009-08-10 3 views
6

Я недавно работал над древовидной структурой, несколькими узлами, несколькими и увеличивающимися уровнями и методом print(). Сначала я подумал, что это должно быть Composite, я тогда записал некоторый возможный дизайн и коды:Какая польза от композитного шаблона приведет меня только к массиву?

alt text

$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); 

Выглядит хорошо, я думаю, и начать кодирование, метод печати() может следовать Итератор образец позже. Но во время кодирования я чувствую, что это слишком сложно для этих простых узлов? И мне приходится создавать множество конкретных классов (более 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']); 
    ... 
} 

Две конструкции очень похожи, теперь я немного запутался, что значение составного шаблона, я я пропустил что-то важное из этого рисунка ?

+2

Мое заключение: образец дизайна замечательный, но не означает, что они всегда предпочтительны. В этом примере, учитывая, что дерево имеет более 1000 + узлов, Composite-реализации требует, таким образом, клиента для создания экземпляров более 1000 объектов, и что? вам нужно обратиться к другому шаблону Flyweight, чтобы повысить производительность и сохранить ресурс. Программа становится все более сложной, наконец, реализуется Composite + Iterator + Flyweight (+ Vistor иногда). Об простой проблеме, которая может быть решена одним классом с помощью массива и одного метода. Наконец, по этому вопросу, мой ответ заключается в том, что Array реализует разыгрывание Pattern. – Edward

ответ

6

Точка composite pattern должна обрабатывать коллекцию объектов, как если бы это был единственный объект (например, для его отображения или записи в файл). Когда вы пишете себя, метод print() может следовать за шаблоном Iterator позже »- ну, точка составного шаблона заключалась бы в том, что вы могли бы вызвать print(), не беспокоясь о том, печатаете ли вы один компонент или должны итерации через все дерево.

Но, похоже, вы не совсем поняли объектно-ориентированное программирование, поскольку вместо этого вы планируете использовать вложенные массивы. Значение использования объектов вместо хешей (для которых имеются массивы PHP) для всего: type safety, что значительно облегчает отладку и обслуживание программ.

+0

Вы правы, я был программистом на длительный период времени, когда в программировании OO, я следую многим принципам и шаблонам, потому что знаю, что они важны, но я действительно не знаю, почему они важны , В моем понимании, OO - это в основном способ упростить программу для изменения, но обычно я не вижу, даже не знаю, эффективна ли она. в этом примере, например, я все еще не вижу, как более низкая цена, которую Composite должна предоставлять, добавлять/удалять узлы, изменять порядок, не являются ли изменения двух кодов одинаковыми? – Edward

+0

Подумайте об этом так: использование массивов вместо объектов аналогично C-программе, которая использует void * для всех параметров метода. –

+0

Я чувствую от вас другой образ мышления, подумайте о реализации Array, я думаю, что это OO-реализация, а не Composite, не так ли? Я могу понять пример, который вы сказали, но мне не помогает понять, используя объекты вместо массива, в этом примере преимущества? – Edward

7

Значение композитного материала заключается в том, что вы продаете некоторую сложность за возможность не сломать инкапсуляцию.

В версии массива вы нарушаете инкапсуляцию, так как вы тестирования, если узел не является лист:

if(isset($node['children'])) $this->print($node['children']); 

с композитными вы можете сказать:

print(); 

затем время выполнения полиморфизма вызовет правильный метод. В этом случае (я не программист PHP, поэтому позвольте мне использовать Java-подобный синтаксис):

class Node { 

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

    ... 
} 

class Leaf { 

    void print() { 
     // print it! 
    } 
} 

еще одно преимущества над простым массивом является то, что вы прятать детали реализации (структуру данных, и т.д.)

+0

Я пытался понять, но до сих пор не могу уловить дух. Ниже приведены мои мысли, не стесняйтесь указывать свои ошибки, я также исправил некоторые ошибки в своих кодах. 1. «Разрыв инкапсуляции», что меня смущает, если я не рассматриваю узел как сущность, это все-таки нарушение инкапсуляции? и какая проблема это вызовет? 2. Я действительно думаю, что детали реализации скрыты в структуре класса, не так ли? 3. Я все еще не могу найти преимущество Composite, независимо от того, как я изменяю это дерево, цены на изменения кода, сделанные двумя способами, кажутся одинаковыми. – Edward

+0

теперь код выглядит лучше: 1. с помощью композита вы не различаете операции над узлами из операций на листах 2. теперь ясно, что ваш массив инкапсулирован в класс; в вашем исходном вопросе это не – dfa

0

Не реализована ли реализация массива намного сложнее? Если я смотрю на это, я должен изучить его ближе, чтобы понять, что вы делаете. Вы имеете дело с индексами, присваиваете записи конкретным индексам и т. Д. ... он выглядит действительно сложным.

Ваша реализация составного рисунка на другом сайте выглядит простым и естественным, когда вы смотрите на код, в котором вы его используете. У вас есть узел, и вы прикрепляете к нему другие узлы или листы. Ничего сложного, странного, мне не нужно заботиться/помнить индексы и т. Д. Вот почему составной шаблон полезен в вашем случае. Конечно, его реализация может выглядеть несколько сложнее, если вы не привыкли к этому, но важный момент (как и другие заявленные) заключается в том, что вы скрываете детали.Это очень важное. Это простой пример, который может по-прежнему работать с вашими массивами, но когда вы реализуете такой код в рабочей среде, где, возможно, другие разработчики могут редактировать/поддерживать ваш код. Если кто-то должен изменить ваше решение «массив», гораздо более вероятно, что он представит новые ошибки.

+0

Я исправил некоторые ошибки в прежних кодах, теперь это должно быть ближе к моему разуму. – Edward