Каков правильный шаблон проектирования, позволяющий объектам найти свой корень в иерархической структуре?


У меня есть иерархическая структура объектов (скажем, 3 уровня).

Класс А состоит из класса в, класс В - из класса С.

Инициализация делает что-то вроде:

$a1 = new A()
$a1->add('B1', $b11 = new B())
$a1->add('B2', $b12 = new B())
$b11->add('C1', $c111 = new C())
$b12->add('C1', $c121 = new C())
...

Моя проблема возникает, когда $c121 хочет получить $c111. В настоящее время я знаю 2 способа добиться этого:

1/ Предположим, что A-это синглет : это дает мне возможность вернуться к корню из любого узла дерева. Затем я могу обратиться к любому узлу из корня с полным "имя пути".

2/ Дайте каждому объекту его предка, чтобы они могли вернуться назад (по ссылке на предка) и вперед (по пути) через дерево.

Хотя оба эти решения удовлетворяют мои потребности, я не могу найти ни одного из них удовлетворяющим.

Я что-то упустил ? Это должно быть общей проблемой, но я не могу понять, какой шаблон дизайна может соответствовать этой проблеме.

Обратите внимание, что иерархия не состоит из подобных элементов. Таким образом, это фиксированная иерархия. Только то, что количество предметов на каждом уровне колеблется. (напр. Клиенты, заказы и заказанные продукты)

2 2

2 ответа:

Если ваши классы несопоставимы, то я бы рассматривал их как таковые (т. е. у вас нет дерева как такового).
Кажется, что вы пытаетесь относиться к несопоставимым элементам, как будто они были чем-то похожи.

Если вам нужен доступ к содержащему классу (который вы называете родительским), вам потребуется предоставить ссылку.

В приведенном выше примере я бы дал вашим связанным объектам ссылку на объект, "удерживающий" его, и дал бы классу C средство для получения его братья и сестры.

$c121=new C(this);   // pass reference to container
$c121->getSiblings();  // method to get sibling through reference to containing object

Другой способ взглянуть на это:

$frank=new Customer()
$frank->add('Order01', $order1 = new Order())
$frank->add('Order02', $order2 = new Order())
$order1->add('LineItem01', $item1 = new LineItem())
$order1->add('LineItem02', $item2 = new LineItem())

$order1->getOrder() //return collection
$order1->getOrder()->getItems() //return collection items/siblings

Сделать оба. В Eclipse, как правило, все инструменты для реализации метода на известный класс, ответы модель корня. Объекты, которые появляются в деревьях (визуально как элементы дерева или с точки зрения реализации как виджет пользовательского интерфейса), все знают своих родителей и могут получить родителя через унаследованный вызов getParent ().