Я борюсь с применением шаблона посетителя на некоторых объектах, имеющих скалярные элементы и в то же время совокупные члены (коллекции).Реализация шаблона посетителя на совокупных объектах
Это те объекты, которые у меня есть:
Artist
- id
- name
- .. more scalar values ..
- worksOfArt <-- this is a collection as WorkOfArt instances
WorkOfArt
- id
- name
- .. more scalar values ..
- artists <-- this is a collection of Artist instances
Как вы можете видеть, структура также будет рекурсивным, но это позднейшего интерес для меня. ;-)
Мой вопрос: какой лучший способ реализовать шаблон посетителя, который позволяет мне посещать объекты, а также только их посещаемые дети (коллекции).
Я думал, что создание интерфейса, как это:
VisitableAggregateInterface
{
public function getVisitableChildren(); // this would return only visitable children
}
А затем пусть как Исполнитель и WorkOfArt расширить абстрактный класс вроде этого:
VisitableAggregateAbstract implements VisitableAggregateInterface
{
public function accept(Visitor $visitor)
{
$visitor->visit($this);
foreach($this->getVisitableChildren() as $visitableChild)
{
$visitableChild->accept($visitor);
}
}
/*
VisitableAggregateInterface::getVisitableChildren()
will be implemented by Artist and WorkOfArt and will only
return visitable children (like collections), and not scalar values.
*/
}
Цель состоит в том, в конечном счете, в конечном итоге с бетоном Посетитель, который выпишет XML-файл, подобный этому:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<artgallery>
<artists>
<artist>
<id>1</id>
<name></name>
<worksOfArt>
<workOfArt refid="11"/>
<workOfArt refid="12"/>
</worksOfArt>
<artist>
<artists>
<worksOfArt>
<workOfArt>
<id>11</id>
<artists>
<artist refid="1"/>
</artists>
<name></name>
<info><![CDATA[some info]]></info>
</workOfArt>
<workOfArt>
<id>12</id>
<artists>
<artist refid="1"/>
</artists>
<name></name>
<info><![CDATA[some info]]></info>
</workOfArt>
</worksOfArt>
</artgallery>
Советуем вам: Я иду в правильном направлении здесь? Потому что интерфейс getVisitableChildren()
чувствует себя немного изворотливым для меня. Должен ли я, возможно, даже вообще сорвать шаблон посетителя и придерживаться другого подхода?
Спасибо.
Вы убедили меня оставить шаблон посетителя. Я не знал, что шаблон посетителя обычно предназначен для рекурсивных данных. Я решил воспользоваться предложенным вами подходом, хотя и немного более гибким, так как мне также нужно выводить частичные фрагменты. Но ты не мог этого знать. Благодарю. –