Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改,接受这个操作的数据结构可以保持不变。
访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。
interface ICarElementVisitor {
void Visit(Wheel wheel);
void Visit(Engine engine);
void Visit(Body body);
void Visit(Car car);
}
interface ICarElement {
void Accept(ICarElementVisitor visitor);
}
class Wheel : ICarElement {
public string Name {
get;
private set;
}
public Wheel(string name) {
this.Name = name;
}
public void Accept(ICarElementVisitor visitor) {
visitor.Visit(this);
}
}
class Engine : ICarElement {
public void Accept(ICarElementVisitor visitor) {
visitor.Visit(this);
}
}
class Body : ICarElement {
public void Accept(ICarElementVisitor visitor) {
visitor.Visit(this);
}
}
class Car : ICarElement {
private readonly ICarElement[] _elements;
public Car() {
this._elements = new ICarElement[] {
new Wheel("front left"),
new Wheel("front right"),
new Wheel("back left"),
new Wheel("back right"),
new Body(),
new Engine()
};
}
public void Accept(ICarElementVisitor visitor) {
foreach (var element in _elements) {
element.Accept(visitor);
}
visitor.Visit(this);
}
}
class CarElementPrintVisitor : ICarElementVisitor {
public void Visit(Wheel wheel) {
Console.WriteLine("visiting {0} wheel", wheel.Name);
}
public void Visit(Engine engine) {
Console.WriteLine("visiting engine");
}
public void Visit(Body body) {
Console.WriteLine("visiting body");
}
public void Visit(Car car) {
Console.WriteLine("visitig car");
}
}
class CarElementDoVisitor : ICarElementVisitor {
public void Visit(Wheel wheel) {
Console.WriteLine("kicking my {0} wheel", wheel.Name);
}
public void Visit(Engine engine) {
Console.WriteLine("starting my engine");
}
public void Visit(Body body) {
Console.WriteLine("moving my body");
}
public void Visit(Car car) {
Console.WriteLine("starting my car");
}
}
class Program {
static void Main(string[] args) {
var car = new Car();
car.Accept(new CarElementPrintVisitor());
car.Accept(new CarElementDoVisitor());
Console.ReadKey();
}
}