Шаблон посетителя .NET C # - PullRequest
1 голос
/ 10 июля 2009

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

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 () перед двойной его отправкой. В рамках обработки определенных объектов я вызываю определенные методы для объектов листьев / дочерних объектов. Теперь, когда я пересекаю дочерний объект (как часть текущей итерации), я не хочу, чтобы AcceptVisitor () выполнял двойную диспетчеризацию чего-либо. (Двойная диспетчеризация вызывает метод для записи текста в выходной файл. Я хочу избежать дублирования текста в файле.) Я получил эту функцию с помощью флага, но меня не устраивает дизайн флага. Есть ли какая-либо измененная версия шаблона посетителя для решения этой конкретной ситуации? Любые другие идеи также приветствуются.

//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 ]

1 голос
/ 29 ноября 2009

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

1 голос
/ 10 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...