访问者模式

来源:互联网 发布:软件项目管理流程文档 编辑:程序博客网 时间:2024/05/01 22:15

    (1)定义:访问者模式,顾名思义使用了这个模式后就可以在不修改已有程序结构的前提下,通过添加额外的“访问者”来完成对已有代码功能的提升。《设计模式》里的定义:表示一个作用于某对象结构中的个元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。从定义可以看出结果对象是使用访问者模式的必须条件,而且这个结构对象必须存在遍历自身各个对象的方法。

 

    (2)组成结构:

1) 访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。

2) 具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。

3)元素角色(Element) :定义一个 Accept 操作,它以一个访问者为参数。

4) 具体元素角色(Concrete Element):实现由元素角色提供的 Accept 操作。

5) 对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。  

 

   (3)例子代码: public interface Visitor{        

                              void visit(Wheel wheel);        

                              void visit(Engine engine);           

                              void visit(Car car);

                         }

                        public interface Element {   

                               public void accep(Visitor v);

                        }  

 

                      public class Engine implements Element{        

                             public void accep(Visitor v) {         

                                   v.visit(this);       

                              }  

                     }

                      public class Car implements Element{   

                            private Engine engine = new Engine();   

                            private Wheel[] wheels ={new Wheel("Font left"),new Wheel("Front right"),

                                                                      new Wheel("Back left"),new   Wheel("Back right")};     

 

                            public void accep(Visitor v) {         

                                      v.visit(this);

                                     engine.accep(v);

                                      for(int i=0;i<4;i++){

                                          wheels[i].accep(v);          

                                       }    

                             }  

                       }  

                      public class Engine implements Element{

                              public void accep(Visitor v) {        

                                    v.visit(this);     

                                }  

                      }

                      public class Engineer implements Visitor{

                               protected String name; 

                               public Engineer(String name){        

                                        this.name=name;     

                               }     

                               public void visit(Wheel wheel) {        

                                       System.out.println("wheel: "+wheel.getName());     

                               }

                               public void visit(Car car) {      

                                         System.out.println(name+": car");    

                               }    

                                public void visit(Engine engine) {        

                                           System.out.println("engine");        

                                 }  

                        }

                        public class App {     

                                  public static void main(String[] args) {        

                                                Car car = new Car();         

                                                Visitor engineer = new Engineer("su");

                                                car.accep(engineer);     

                                    }  

                         }

 

     (4)优缺点和适用情况。       

使用了访问者模式以后,对于原来的类层次增加新的操作,仅仅需要实现一个具体访问者角色就可以了,而不必修改整个类层次。而且这样符合“开闭原则”的要求。而且每个具体的访问者角色都对应于一个相关操作,因此如果一个操作的需求有变,那么仅仅修改一个具体访问者角色,而不用改动整个类层次。由于访问者模式为我们的系统多提供了一层“访问者”,因此我们可以在访问者中添加一些对元素角色的额外操作。但是“开闭原则”的遵循总是片面的。如果系统中的类层次发生了变化,会对访问者模式产生什么样的影响呢?你必须修改访问者角色和每一个具体访问者角色……看来访问者角色不适合具体元素角色经常发生变化的情况。而且访问者角色要执行与元素角色相关的操作,就必须让元素角色将自己内部属性暴露出来,而在 java中就意味着其它的对象也可以访问。这就破坏了元素角色的封装性。而且在访问者模式中,元素与访问者之间能够传递的信息有限,这往往也会限制访问者模式的使用。《设计模式》一书中给出了访问者模式适用的情况:   

1) 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。   

2) 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor使得你可以将相关的操作集中起来定义在一个类中。   

3) 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。   

4) 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

原创粉丝点击