访问者接口
csharp
public interface IVisitor
{
void Visit(Circle circle);
void Visit(Rectangle rectangle);
}
具体访问者
csharp
public class AreaVisitor : IVisitor
{
public void Visit(Circle circle)
{
double area = Math.PI * circle.Radius * circle.Radius;
Console.WriteLine($"Circle area: {area}");
}
public void Visit(Rectangle rectangle)
{
double area = rectangle.Width * rectangle.Height;
Console.WriteLine($"Rectangle area: {area}");
}
}
public class DrawVisitor : IVisitor
{
public void Visit(Circle circle)
{
Console.WriteLine("Drawing a circle");
}
public void Visit(Rectangle rectangle)
{
Console.WriteLine("Drawing a rectangle");
}
}
元素接口
csharp
public interface IShape
{
void Accept(IVisitor visitor);
}
具体元素
csharp
public class Circle : IShape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
客户端代码
csharp
class Program
{
static void Main(string[] args)
{
List shapes = new List
{
new Circle(5),
new Rectangle(4, 6)
};
IVisitor areaVisitor = new AreaVisitor();
IVisitor drawVisitor = new DrawVisitor();
foreach (var shape in shapes)
{
shape.Accept(areaVisitor);
shape.Accept(drawVisitor);
}
}
}
应用场景

访问者这个模式, 它适合用在下面所提到的这几个场景里头。
当对象的结构保持稳定, 但还非得在对象结构上定下新的操作不可的时候, 就可以用到访问者模式这种说法。如果必须要对对象里面的元素做出不一样的处理, 而且这些处理方式变来变去, 改得挺勤快的话, 也可以使用访问者模式来应对。
如果不愿意让元素类本身变得杂乱,不想往元素类里头硬塞更多的操作逻辑, 那么就可以把操作的部分单独拉出来放一边, 采用访问者模式这种方式来实现分离。优缺点
优点
缺点