访问者模式
概念
①、什么是访问者模式
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变个元素的类的前提下定义作用于这些元素的操作
②、访问者模式中例子为什么是男人、女人呢,与访问者是什么关联呢,谁是访问者,谁是被访问者?
个人理解:我们将对象结构看成是一个“房间”,将男人女人实例化到对象结构中去,可以看做是在对象结构这个“屋子”中放入一个男人,一个女人,他(她)们的身份是被访问者。此时状态(成功)作为访问者进入房间后依次访问男人、女人并实现他们;随后状态(失败)也作为一个访问者去对象结构这个“房间”逐一访问男人、女人并实现他们。
③、主要解决什么问题
作用于结构上的操作之间的耦合、(把处理从数据结构分离)
④、如何解决
在被访问的类里面加一个对外提供接待访问者的接口。(本例中对象结构就是这个接口)
⑤、使用场景?
1.对象结构中对象对应的类很少改变,但经常要在此对象结构上定义新的操作
2.需要对一个对象结构中的对象进行很多不同的并不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类
⑥、优缺点
优点
1.符合单一职责原则
2.优秀的扩展性
3.灵活性
缺点
具体元素对访问者公布细节,违反了迪米特法则
具体元素变更比较困难
违反了依赖倒置原则依赖了具体类,没有以来抽象
图
代码
1.代码类图
客户端
static void Main(string[] args) { //创建对象结构。冰箱结构中添加具体对象 ObjectStructure o = new ObjectStructure(); //用对象结构类实例化一个o对象,创建一个集合,用来存放元素 o.Attach(new Man()); //使用对象节后得添加方法,添加一个Man类对象 o.Attach(new Woman()); //调用对象结构得添加方法,添加一个Woman类对象 //成功时的反应 Success v1 = new Success(); //实例化具体状态,成功类对象 o.Display(v1); //调用对象结构得显示方法,把实例化得成功类对象作为参数传递过去 //失败时的反应 Failing v2 = new Failing(); o.Display(v2); //恋爱时的反应 Amativeness v3 = new Amativeness(); o.Display(v3); Console.Read(); }
状态的抽象类
abstract class Action { //得到男人的反应或结论 public abstract void GetManConclusion(Man concreteElementA); //得到女人的结论或反应 public abstract void GetWomanConclusion(Woman concreteElementB); }
人的抽象类
abstract class Person { //接受 public abstract void Accept(Action visitor); //人类得接受方法,接受得内容是什么,括号内得参数:状态 }
男人类
//男人 class Man:Person { public override void Accept(Action visitor) { visitor.GetManConclusion(this); //在客户端中将具体状态作为参数传递给“男人”类完成一次分配,然后“男人”类调用作为参数得“具体状态”中得方法“男人反应”同时将自己得(this)作为参数传递进去,完成第二次分配 } }
女人类
//女人 class Woman:Person { public override void Accept(Action visitor) { visitor.GetWomanConclusion(this); } }
状态类:成功时
//成功时 class Success:Action { public override void GetManConclusion(Man concreteElementA) { Console.WriteLine("{0} {1}时,背后有一个伟大的女人", concreteElementA.GetType().Name, this.GetType().Name); } public override void GetWomanConclusion(Woman concreteElementB) { Console.WriteLine("{0} {1} 时,背后有一个不成功的男人,", concreteElementB.GetType().Name, this.GetType().Name); } }
失败时
//失败时 class Failing:Action { public override void GetWomanConclusion(Woman concreteElementB) { Console.WriteLine("{0} {1}时,眼泪汪汪,谁也劝不了", concreteElementB.GetType().Name, this.GetType().Name); } public override void GetManConclusion(Man concreteElementA) { Console.WriteLine("{0} {1}时,门头喝酒,谁也不用全", concreteElementA.GetType().Name, this.GetType().Name); } }
恋爱时
//恋爱时 class Amativeness:Action { public override void GetManConclusion(Man concreteElementA) { Console.WriteLine("{0} {1}时,凡事不懂也要装懂", concreteElementA.GetType().Name, this.GetType().Name); } public override void GetWomanConclusion(Woman concreteElementB) { Console.WriteLine("{0} {1} 时,凡是动也装作不懂,", concreteElementB.GetType().Name, this.GetType().Name); } }
对象结构类
//对象结构 class ObjectStructure { private IList<Person> elements = new List<Person>(); //增加 public void Attach(Person element ) { elements.Add(element); } //移除 public void Detach(Person element ) { elements.Remove(element); } //显示查看 public void Display(Action visitor ) { foreach (Person e in elements ) { e.Accept(visitor); } } }