读书笔记19:访问者模式

1、定义:表示作用于某对象结构中的个元素的操作。它使你可以在不改变个元素的类的前提下定义作用于这些元素的新操作。
2、角色:
抽象访问者角色(Visitor):声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。 
具体访问者角色(CreateVisitor):实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。 
抽象节点角色(Element):声明一个接受操作,接受一个访问者对象作为一个参量。 
具体节点角色(CreateElement):实现了抽象元素所规定的接受操作。 
结构对象角色(ObiectStructure):有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。

访问者模式比较抽象,其基本想法是:首先我们拥有一个由许多对象构成的对象结构(ObiectStructure),这些对象的类都拥有一个accept方法用来接受访问者对象;访问者(Visitor)是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素(CreateElement)作出不同的反应;在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。
3、模型:
抽象的访问者,为其中的CreateElement提供Visit方法。

[csharp]  view plain copy print ?
  1. public abstract class Vistor  
  2.  {  
  3.      public abstract void VisitConcreteElementA(CreateElementA createElementA);  
  4.   
  5.      public abstract void VisitConcreteElementB(CreateElementB createElementB);  
  6.  }  

具体访问者,实现Visit方法。每个操作实现算法的一部分,而该算法片段对应于结构中对象的类,即模型中的Element及其子类。

[csharp]  view plain copy print ?
  1. public class CreateVisitor1:Vistor  
  2. {  
  3.     public override void VisitConcreteElementA(CreateElementA createElementA)  
  4.     {  
  5.         Console.WriteLine(string.Format("{0}被{1}访问", createElementA.GetType().Name, this.GetType().Name));  
  6.     }  
  7.   
  8.     public override void VisitConcreteElementB(CreateElementB createElementB)  
  9.     {  
  10.         Console.WriteLine(string.Format("{0}被{1}访问", createElementB.GetType().Name, this.GetType().Name));  
  11.     }  
  12. }  
  13.   
  14. public class CreateVisitor2 : Vistor  
  15. {  
  16.     public override void VisitConcreteElementA(CreateElementA createElementA)  
  17.     {  
  18.         Console.WriteLine(string.Format("{0}被{1}访问", createElementA.GetType().Name, this.GetType().Name));  
  19.     }  
  20.   
  21.     public override void VisitConcreteElementB(CreateElementB createElementB)  
  22.     {  
  23.         Console.WriteLine(string.Format("{0}被{1}访问", createElementB.GetType().Name, this.GetType().Name));  
  24.     }  
  25. }  

 抽象节点,内有Accept操作,以一个访问者问参数。

[csharp]  view plain copy print ?
  1. public abstract class Element  
  2. {  
  3.     public abstract void Accept(Vistor visitor);  
  4. }  
  5. public class CreateElementA : Element  
  6. {  
  7.   
  8.     public override void Accept(Vistor visitor)  
  9.     {  
  10.         visitor.VisitConcreteElementA(this);  
  11.     }  
  12.   
  13.     public void OperationA()  
  14.     {  
  15.     }  
  16. }  

实现抽象节点的类。

[csharp]  view plain copy print ?
  1. public class CreateElementB : Element  
  2. {  
  3.   
  4.     public override void Accept(Vistor visitor)  
  5.     {  
  6.         visitor.VisitConcreteElementB(this);  
  7.     }  
  8.   
  9.     public void OperationB()  
  10.     {  
  11.   
  12.     }  
  13. }  

结构类。

[csharp]  view plain copy print ?
  1. public class ObjectStructs  
  2. {  
  3.     private List<Element> elements = new List<Element>();  
  4.   
  5.     public void Attach(Element element)  
  6.     {  
  7.         elements.Add(element);  
  8.     }  
  9.   
  10.     public void Detach(Element element)  
  11.     {  
  12.         elements.Remove(element);  
  13.     }  
  14.   
  15.     public void Accept(Vistor vistor)  
  16.     {  
  17.         foreach (Element e in elements)  
  18.         {  
  19.             e.Accept(vistor);  
  20.         }  
  21.     }  
  22. }  

访问者模式目的是将数据结构和操作分开,这样就可以方便的增加新的操作而不用在数据结构中改动。比如,有一个数据结构里面含有一个Person对象和一个针对person的操作Operat1。

[csharp]  view plain copy print ?
  1. public class Person  
  2. {  
  3. }  
  4.   
  5. public class MyStructs  
  6. {  
  7.     Person person = null;  
  8.   
  9.     public void Operat1() { }  
  10. }  

 调用

[csharp]  view plain copy print ?
  1.  static void Main(string[] args)  
  2. {  
  3.     ObjectStructs objectStructs = new ObjectStructs();  
  4.   
  5.     objectStructs.Attach(new CreateElementA());  
  6.   
  7.     objectStructs.Attach(new CreateElementB());  
  8.   
  9.     CreateVisitor1 visitor1 = new CreateVisitor1();  
  10.   
  11.     CreateVisitor2 visitor2 = new CreateVisitor2();  
  12.   
  13.     objectStructs.Accept(visitor1);  
  14.   
  15.     objectStructs.Accept(visitor2);  
  16.   
  17.     Console.ReadLine();  
  18. }  

结果

    但是,现在有了另一个需求,我想再增加一个Operat2操作。直接在MyStructs中增加?假如又想增加3,4,5多个操作呢,那就不停的去修改结构,这不符合开放封闭原则的。那么按照访问者模式,在最初定义结构的时候就提供一让外部可访问的接口。这样每增加一个操作我不去修改结构了,只需增加一个访问者就可以了。具体的操作写在CreateElement中。每一个访问者需要操作person,就去对应的CreateElement中去操作就行了。

代码模型:http://download.csdn.net/detail/yysyangyangyangshan/4140330

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值