我们来实现这几句话:
abstractclass Action
{
//男人时的结论
public abstract void GetManColclusion(Man x);
//女人时的结论
public abstract void GetWomanColclusion(Woman x);
};
abstractclass Person
{
public abstract void Accept(Action a);
};
//成功时
class Success :Action
{
public override void GetManColclusion(Man x)
{
Console.WriteLine("when {0} {1},there must be a women behind", x.GetType().Name, this.GetType().Name);
}
public override void GetWomanColclusion(Woman x)
{
Console.WriteLine("when {0} {1},there must be a failed man", x.GetType().Name, this.GetType().Name);
}
};
//失败时
class Failing :Action
{
//同上
};
class Man :Person
{
public override void Accept(Action a)
{
a.GetManColclusion(this);
}
};
//要注意的是, 这里使用了双分派技术,首先在客户程序中将具体状态作为参数传递给“男人类”,完成一次分派,然后男人类调用作为参数的具体状态中的方法MenConclusion, 同时将自己作为参数传递进去,完成二次分派
//双分派意味着得到执行的操作决定于请求的种类和两个接收者的类型。
class Woman :Person
{
public override void Accept(Action a)
{
a.GetWomanColclusion(this);
}
};
//下面这个是将这男女整合在一起输出用的
class ObjectStructure
{
private IList<Person> es = newIList<Person>();
//增加
public void Add(Person e)
{
es.Add(e);
}
//移除
public void Remove(Person e)
{
e.Remove(e);
}
//根据状态显示该条信息
public void Display(Action a)
{
foreach (Person var in es)
{
var.Accept(a);
}
}
};
void main()
{
ObjectStructure os = new ObjectStructure();
os.Add(new Man());
os.Add(new Woman());
Success s = new Success();
os.Display(s);
Failing f = new Failing();
os.Display(f);
}
从上面的代码可以看出来,如果不止有男女性别,还会出现其他,那么这个模式是不成立的,因为一旦增加除了男女的类,那么许多类就需要内部修改了,这样就违背了开闭原则。
所以,访问者模式适用于数据结构相对稳定的系统。
它把数据结构和作用于结构上的操作之间的耦合解开,使得操作集合可以相对自由的演化。
访问者模式的主要目的是把处理从数据结构分离出来。
访问者模式的优点是增加新的操作很容易,因为增加新的操作就意味着增加一个新的访问者。访问者模式将有关的行为集中到一个访问者对象中。
而访问者模式的缺点就是使增加新的数据结构变得困难了。
这就是访问者模式,表示一个用作于某对象结构中的各个元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作
下面为访问者模式基本结构:
abstract class Visitor
{
public abstract voidVisitConcreteElementA(ConcreteElementA concreteElementA);
public abstract voidVisitConcreteElementB(ConcreteElementB concreteElementB);
}
class ConcreteVisitor1 : Visitor
{
public override voidVisitConcreteElementA(ConcreteElementA concreteElementA)
{
Console.WriteLine("{0}被{1}访问", concreteElementA.GetType().Name, this.GetType().Name);
}
public override voidVisitConcreteElementB(ConcreteElementB concreteElementB)
{
Console.WriteLine("{0}被{1}访问", concreteElementB.GetType().Name, this.GetType().Name);
}
}
class ConcreteVisitor2 : Visitor
{
//同上
}
abstract class Element
{
public abstract void Accept(Visitor visitor);
}
class ConcreteElementA : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementA(this);
}
public void OperationA()
{ }
}
class ConcreteElementB : Element
{
public override void Accept(Visitor visitor)
{
visitor.VisitConcreteElementB(this);
}
public void OperationB()
{ }
}
class ObjectStructure
{
private IList<Element> elements = new List<Element>();
public void Attach(Element element)
{
elements.Add(element);
}
public void Detach(Element element)
{
elements.Remove(element);
}
public void Accept(Visitor visitor)
{
foreach (Element e in elements)
{
e.Accept(visitor);
}
}
}
void Main(string[] args)
{
ObjectStructure o = new ObjectStructure();
o.Attach(new ConcreteElementA());
o.Attach(new ConcreteElementB());
ConcreteVisitor1 v1 = new ConcreteVisitor1();
ConcreteVisitor2 v2 = new ConcreteVisitor2();
o.Accept(v1);
o.Accept(v2);
Console.Read();
}