C# 如何实现用于生成XML的访问者模式?
我有一个包含许多类的复合类结构。由于许多不同的原因(验证、克隆、导出为xml等),需要遍历此结构,因此编写使用访问者模式是有意义的。给定以下类结构C# 如何实现用于生成XML的访问者模式?,c#,java,design-patterns,visitor-pattern,C#,Java,Design Patterns,Visitor Pattern,我有一个包含许多类的复合类结构。由于许多不同的原因(验证、克隆、导出为xml等),需要遍历此结构,因此编写使用访问者模式是有意义的。给定以下类结构 class Owner { public string Name { get; set; } public List<Owned> Liked { get; private set; } public List<Owned> Disliked { get; private set; } pub
class Owner
{
public string Name { get; set; }
public List<Owned> Liked { get; private set; }
public List<Owned> Disliked { get; private set; }
public Owner()
{
this.Liked = new List<Owned>();
this.Disliked = new List<Owned>();
}
}
class Owned
{
public string Name { get; set; }
}
类所有者
{
公共字符串名称{get;set;}
公共列表{get;private set;}
不喜欢的公共列表{get;private set;}
公共所有者()
{
this.Liked=newlist();
this.Disliked=新列表();
}
}
阶级所有
{
公共字符串名称{get;set;}
}
如果我想生成这样的XML,应该如何实现这样的访问者模式
<owner>
<name>Owner 1</name>
<likedThings>
<owned>
<name>Liked thing 1</name>
</owned>
<owned>
<name>Liked thing 2</name>
</owned>
</likedThings>
<dislikedThings>
<owned>
<name>Disliked thing 1</name>
</owned>
<owned>
<name>Disliked thing 2</name>
</owned>
</dislikedThings>
</owner>
业主1
喜欢的东西1
喜欢的东西2
不喜欢的事情1
不喜欢的事情2
我关心的第一件事是,通常我会有VisitOwner和VisitOwned,这对于验证来说很好,但在XML中,我需要将拥有的对象包装在它们各自喜欢或不喜欢的XML节点中
我关心的第二件事是,对于尚未为组合的任何新部分实现操作的每个现有访问者实现(例如,新属性“List Studythings”)允许您为问题的双重分派端构建结构,帮助您处理由于模型的继承结构而导致的复杂性。但是,模式的经典形式并不能处理由于模型的组合结构而导致的复杂性,特别是当同一类以不同的容量多次使用时
在您的情况下,解决方案必须解决这两个复杂性-一方面,您拥有所有者
而不是所有者
;另一方面,您有喜欢的
,不喜欢的
,以及您计划添加的任何其他内容
处理组合端的任务传统上交给访问者的实现,而不是接口。但是,编译器将无法帮助您找到无法处理新关系的违规者。但是,您可以将访问者模式与结合起来,创建一个处理这两个问题的混合解决方案
以下是您可以执行的操作的框架:
// This is a run-of-the-mill visitor
interface IVisitor {
void VisitOwner(Owner owner);
void VisitOwned(Owned owned);
}
// This is a base visitor class; it is abstract
abstract class DefaultVisitor : IVisitor {
public void VisitOwner(Owner owner) {
BeginOwner(owner);
BeginLiked();
foreach (var owned in owner.Liked) {
owned.Accept(this);
}
EndLiked();
BeginDisliked();
foreach (var owned in owner.Disliked) {
owned.Accept(this);
}
EndDisliked();
EndOwner(owner);
}
public void VisitOwned(Owned owned) {
BeginOwned(owned);
EndOwned(owned);
}
public abstract void BeginOwner(Owner owner);
public abstract void EndOwner(Owner owner);
public abstract void BeginOwned(Owned owned);
public abstract void EndOwned(Owned owned);
public abstract void BeginLiked();
public abstract void EndLiked();
public abstract void BeginDisliked();
public abstract void EndDisliked();
}
这样构造代码的好处是编译器现在可以检查DefaultVisitor
的实现是否存在所有抽象方法;缺点是这些实现必须提供八个实现,而不是两个