访问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式。据《大话设计模式》中说算是最复杂也是最难以理解的一种模式了。
定义(源于GoF《Design Pattern》):表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
类图如下
IElement
public interface IElement
{
void Accept(IVisitor visitor);
}
ConcreteElement1
public class ConcreteElement1 : IElement
{
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
ConcreteElement2
public class ConcreteElement2 : IElement
{
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
IVisitor
public interface IVisitor
{
void Visit(ConcreteElement1 element1);
void Visit(ConcreteElement2 element2);
}
ConcreteVisitorA
public class ConcreteVisitorA : IVisitor
{
public void Visit(ConcreteElement1 element1)
{
Console.WriteLine("visit ConcreteElement1 in ConcreteVisitorA");
}
public void Visit(ConcreteElement2 element2)
{
Console.WriteLine("visit ConcreteElement2 in ConcreteVisitorA");
}
}
ConcreteVisitorB
public class ConcreteVisitorB : IVisitor
{
public void Visit(ConcreteElement1 element1)
{
Console.WriteLine("visit ConcreteElement1 in ConcreteVisitorB");
}
public void Visit(ConcreteElement2 element2)
{
Console.WriteLine("visit ConcreteElement2 in ConcreteVisitorB");
}
}
ObjectStruct
public class ObjectStruct
{
private List<IElement> elements;
public ObjectStruct()
{
elements = new List<IElement>();
}
public void Accept(IVisitor visitor)
{
foreach (var item in this.elements)
{
item.Accept(visitor);
}
}
public void Add(IElement element)
{
this.elements.Add(element);
}
public void Remove(IElement element)
{
this.elements.Remove(element);
}
}
调用
static void Main(string[] args)
{
ObjectStruct objectStruct = new ObjectStruct();
objectStruct.Add(new ConcreteElement1());
objectStruct.Add(new ConcreteElement2());
ConcreteVisitorA concreteVisitorA = new ConcreteVisitorA();
objectStruct.Accept(concreteVisitorA);
ConcreteVisitorB concreteVisitorB = new ConcreteVisitorB();
objectStruct.Accept(concreteVisitorB);
}
优点:
- 方便数据操作的扩展
- 将数据结构与数据的操作解耦,符合单一职责
缺点:
- 不利于数据结构的扩展(由于IVisitor接口需要对具体元素的依赖,增加具体元素类需要修改IVisitor接口)
- 破坏了类的三大要素封装性,具体元素类需要对访问者公布细节
- 违反依赖倒置原则, IVisitor接口以来具体元素类
源代码地址: 点击我下载 提取码: r3x8