2009-07-09 3 views
1

Я проанализировал XML-файл в объекты, в которых каждый объект имеет отношение 1: 1 с узлом XML в файле. Это дерево объектов реализует Композитные и публичные шаблоны проектирования согласно следующей записи блога Джереми Миллер:.NET C# Visitor Pattern

http://codebetter.com/blogs/jeremy.miller/archive/2007/10/31/be-not-afraid-of-the-visitor-the-big-bad-composite-or-their-little-friend-double-dispatch.aspx

Когда я перебирать дерево объектов, я сделать некоторые обработки в AcceptVisitor метод() перед двойной диспетчеризации его. В качестве части обработки некоторых объектов я вызываю определенные методы для объектов leafs/children. Теперь, когда я пересекаю дочерний объект (как часть текущей итерации), я не хочу, чтобы AcceptVisitor() дважды отправлял сообщение. (Метод двойной отправки вызова для ввода текста в выходной файл. Я хочу избежать дублирования текста в файле.) Я достиг этой функциональности с флагом, но меня не устраивает дизайн флага. Есть ли модифицированная версия шаблона Visitor для обработки этой конкретной ситуации? Любые другие идеи также приветствуются.

//Iterate object tree 
public void Iterate(Root root) 
{ 
     foreach (ILeaf child in root.ChildLeaves) 
     { 
      child.AcceptVisitor(this); 
     } 
} 

//This method in child object of type ILeaf gets called when Iterate() executes. 
public void AcceptVisitor(IVisitor visitor) 
{ 
     //Some child object implement ILeaf1 along with ILeaf 
     //I want to avoid any processing in AcceptVisitor() for objects of type ILeaf1 
     //once following loop executes. 
     //This means Iterate() should not process anyting in AcceptVisitor() for 
     //children of type ILeaf1. 
     IEnumerable<ILeaf1> children = this.ChildLeaves.OfType<ILeaf1>();   
     //Collection of action statements from child objects.   
     List<ActionStatement> statements = new List<ActionStatement>();   
     foreach (ILeaf1 s in children) 
     { 

      ActionStatement statement = s.Generate(); 
      statements.Add(statement);  
     } 
     //Output action statements to TextWriter 
     visitor.WriteStatements(statements); 
} 

//ILeaf1 object method 
public void AcceptVisitor(IVisitor visitor) 
{ 
     ActionStatement statement = new ActionStatement("Some Text"); 
     //Output action statement to TextWriter 
     visitor.WriteStatement(statement); 
} 
+2

Почему, создайте AcceptVisitor2(), конечно;) – zvolkov

+0

Добавьте код, чтобы проиллюстрировать этот второй абзац, его неясный (по крайней мере, мне), что делает ваш Accept() и как вы хотите, чтобы он вел себя так. –

+0

шаблоны дизайна гниют ум! – Eric

ответ

1

Я даже не вижу, где посетитель используется в вашем AcceptVisitor (IVisitor). При этом, если вам нужна другая реализация для исключений, вы можете передать в свою функцию двух делегатов, один для проверки для специального случая, а другой - для описания того, что вы хотите сделать по-другому для этого особого случая. В качестве альтернативы, специальный случай реализует другой интерфейс в дополнение к вашим обычным и проверяет его (если ваша реализация позволяет, ваше описание/код очень нечеткие).

+0

Я обновил образец кода. – rxm0203

1

нет необходимости в реализации этой сложной структуры в .NET C#. мы можем реализовать шаблон посетителя как метод расширения. Как вам известно, с помощью метода расширения вы можете добавлять новые функции в класс без доступа или изменения класса.