动机:表示一个作用于某对象结构中的各元素的操作。它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。
场景:图形系统,假设其图像种类稳定,而其可提供的操作变化。
结构
![Visitor模式结构图](/images/cnblogs_com/charly/DesignPatternNote/Visitor.gif)
代码
namespace DesignPattern.Visitor
{
public abstract class Shape
{
public abstract void Draw();
![](/Images/OutliningIndicators/InBlock.gif)
// 第二次分发
public abstract void Accept(ShapeVisitor visitor);
}
![](/Images/OutliningIndicators/InBlock.gif)
public class Rectangle : Shape
{
public override void Draw()
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Accept(ShapeVisitor visitor)
{
visitor.Visit(this);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class Circle : Shape
{
public override void Draw()
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Accept(ShapeVisitor visitor)
{
visitor.Visit(this);
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class Line : Shape
{
public override void Draw()
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Accept(ShapeVisitor visitor)
{
visitor.Visit(this);
}
}
}
namespace DesignPattern.Visitor
{
public abstract class ShapeVisitor
{
public abstract void Visit(Rectangle rectangle);
public abstract void Visit(Circle circle);
public abstract void Visit(Line line);
}
![](/Images/OutliningIndicators/InBlock.gif)
public class ScaleVisitor : ShapeVisitor
{
public override void Visit(Rectangle rectangle)
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Visit(Circle circle)
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Visit(Line line)
{
}
}
![](/Images/OutliningIndicators/InBlock.gif)
public class MoveVisitor : ShapeVisitor
{
public override void Visit(Rectangle rectangle)
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Visit(Circle circle)
{
}
![](/Images/OutliningIndicators/InBlock.gif)
public override void Visit(Line line)
{
}
}
}
namespace DesignPattern.Visitor
{
public class Application
{
ShapeVisitor visitor;
![](/Images/OutliningIndicators/InBlock.gif)
public Application(ShapeVisitor visitor)
{
this.visitor = visitor;
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Process(Shape shape)
{
shape.Accept(visitor);// 第一次分发
}
}
}
要点:
1、本模式通过所谓双重分发来实现在不更改Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作。
2、所谓双重分发即本模式中包含两个多态分发,第一个为Accept方法的多态辨析,第二个为Visit方法的多态辨析。
3、本模式最大的缺点在于扩展类层次结构(增加新的Element子类),会导致Visitor类的改变。因此本模式适用于“Element类层次结构稳定,而其中的操作却面临频繁变动”。
场景:图形系统,假设其图像种类稳定,而其可提供的操作变化。
结构
![Visitor模式结构图](/images/cnblogs_com/charly/DesignPatternNote/Visitor.gif)
代码
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
要点:
1、本模式通过所谓双重分发来实现在不更改Element类层次结构的前提下,在运行时透明地为类层次结构上的各个类动态添加新的操作。
2、所谓双重分发即本模式中包含两个多态分发,第一个为Accept方法的多态辨析,第二个为Visit方法的多态辨析。
3、本模式最大的缺点在于扩展类层次结构(增加新的Element子类),会导致Visitor类的改变。因此本模式适用于“Element类层次结构稳定,而其中的操作却面临频繁变动”。
![](http://www.cnblogs.com/Emoticons/qface/055243803.gif)