简介:
访问者模式的意图是主要将数据结构与数据操作分离。
介绍:
优点 | 1.易于添加新的访问者类。 2.行为操作集中到结构对象,,类似中介模式。 |
缺点 | 1.每增加一个节点,抽象访问者也需变动。 2.具体节点元素对访问者公布细节,违反了“迪米特原则”。 3.抽象访问者依赖了具体节点类,违反了“依赖倒置原则”。 |
特点 | 1.适用于Element类层次结构稳定,又有易于变动的算法。变动的是Visitor,不变的是Element。 |
抽象访问者角色(Vistor) | 定义针对多个具体节点角色的操作的接口。 |
具体访问者角色(ConcreteVistor) | 实现抽象访问者的接口。 |
抽象节点角色(Element) | 定义抽象节点接口,包含一个接受访问者对象作为参数。 |
具体节点角色(ConcreteElement) | 实现抽象节点的接口。 |
结构对象角色(ObjectStructure) | 访问者对节点对象处理的入口。 |
访问者模式:可以访问属于不同的等级结构的成员对象。
迭代器模式:只能访问属于同一个等级结构的成员对象。
使用:
本案例的意思是老师、家长等访问者对学生画图作业的评价、评分等等。
//Element
public interface IShape
{
void Draw();
void Accept(ShapeVisitor visitor);
}
//Visitor
public abstract class ShapeVisitor
{
public abstract void Visit(Square shape);
public abstract void Visit(Circle shape);
}
//ConcreteVisitor
public sealed class Parent : ShapeVisitor
{
public override void Visit(Square shape)
{
//do something
}
public override void Visit(Circle shape)
{
//do something
}
}
//ConcreteVisitor
public sealed class Teacher : ShapeVisitor
{
public override void Visit(Square shape)
{
//do something
}
public override void Visit(Circle shape)
{
//do something
}
}
//ConcreteElement
public sealed class Square:IShape
{
public void Draw()
{
//do something
}
public void Accept(ShapeVisitor visitor)
{
visitor.Visit(this);
}
}
//ConcreteElement
public sealed class Circle : IShape
{
public void Draw()
{
//do something
}
public void Accept(ShapeVisitor visitor)
{
visitor.Visit(this);
}
}
//ObjectStructure
public sealed class ShapeStructure
{
private ShapeVisitor _visitor;
public ShapeStructure(ShapeVisitor visitor)
{
_visitor = visitor;
}
public void Process(IShape shape)
{
shape.Accept(_visitor);
}
}
//访问者模式调用
ShapeVisitor visitorPar = new Parent();
ShapeStructure shapeS = new ShapeStructure(visitorPar);
Square square = new Square();
square.Draw(); //节点操作
shapeS.Process(square); //访问者操作
Circle circle = new Circle();
circle.Draw();
shapeS.Process(circle);
ShapeVisitor visitorTea = new Teacher();
shapeS = new ShapeStructure(visitorTea);
square.Draw();
shapeS.Process(square);
circle.Draw();
shapeS.Process(circle);