`
liushilang
  • 浏览: 86260 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

设计模式——访问者模式(Visitor)

阅读更多

访问者模式可在不修改已有程序结构前提下,定义该类层次结构的操作,通过添加额外的访问者来完成对已有代码功能的提升,满足新增加的需求。
结构对象是使用访问者模式必须条件,且这个结构对象必须存在遍历自身各个对象的方法。类似于java中的collection概念了。
访问器类的开发人员必须清楚将要访问类层次结构的全部或部分设计细节。另在设计访问器类时,我们必须特别注意被访问的对象模型中可能会出现环状结构。
一、组成角色
1、访问者角色(Visitor):为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。
2、具体访问者角色(Concrete Visitor):实现每个由访问者角色(Visitor)声明的操作。
3、元素角色(Element):定义一个Accept操作,它以一个访问者为参数。
4、具体元素角色(Concrete Element):实现由元素角色提供的Accept操作。
5、对象结构角色(Object Structure):这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素;可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。
二、类图

设计模式鈥斺敺梦收吣J(Visitor)
Visitor模式可让不同的访问者对同一个对象集合进行访问;Visitor先调用Visitable类的方法,这个方法又回调到Visitor类。
首先要在原有类层次结构中添加accept方法,然后将这个类层次中的类放到一个对象结构中去,再去创建访问者角色。
三、实现
1、元素接口Visitable
package com.makocn.javapatterns.visitor;
public interface Visitable {
 public void accept(Visitor visitor);
}
2、具体元素类NodeA、NodeB、NodeC
package com.makocn.javapatterns.visitor;
public class NodeA implements Visitable {
 public void accept(Visitor visitor) {
  visitor.visit(this);
 }
}
package com.makocn.javapatterns.visitor;
public class NodeB implements Visitable {
 public void accept(Visitor visitor) {
  visitor.visit(this);
 }
}
package com.makocn.javapatterns.visitor;
public class NodeC implements Visitable {
 public void accept(Visitor visitor) {
  visitor.visit(this);
 }
}
3、访问者接口Visitor
package com.makocn.javapatterns.visitor;
import java.util.Collection;
public interface Visitor {
   public void visit(NodeA nodeA);
   public void visit(NodeB nodeB);
   public void visit(NodeC nodeC);
   public void visitCollection(Collection  collection);
}
4、具体访问者类VisitorA
package com.makocn.javapatterns.visitor;
import java.util.Collection;
import java.util.Iterator;
public class VisitorA implements Visitor {
 public void visit(NodeA a) {
  System.out.println("Execute visitNodeA method!");
 }
 public void visit(NodeB b) {
  System.out.println("Execute visitNodeB method!");
 }
 public void visit(NodeC c) {
  System.out.println("Execute visitNodeC method!");
 }
 public void visitCollection(Collection collection) {
  Iterator iterator = collection.iterator();
  while (iterator.hasNext()) {
   Object o = iterator.next();
   if (o instanceof Visitable)
    ((Visitable) o).accept(this);
  }
 }
}
5、客户端测试类VisitorTest
package com.makocn.javapatterns.visitor;
import java.util.ArrayList;
import java.util.List;
public class VisitorTest {
 public static void main(String[] args) {
  NodeA nodeA = new NodeA();
  NodeB nodeB = new NodeB();
  NodeC nodeC = new NodeC();
  VisitorA visitorA = new VisitorA();
  visitorA.visit(nodeA);
  visitorA.visit(nodeB);
  visitorA.visit(nodeC);
  List<Visitable> list = new ArrayList<Visitable>();
  list.add(nodeA);
  list.add(nodeB);
  list.add(nodeC);
  visitorA.visitCollection(list);
 }
}
对象结构这里没有实现,其元素类直接在客户端直接生成。有兴趣都可以去实现下。
在两个接口Visitor和Visitable中,确保Visitable很少变化,也就是说,确保不能老有新的Element元素类型加进来,可以变化的是访问者行为或操作,也就是Visitor的不同子类可以有多种,这样使用访问者模式最方便。
当然可采用java反射机制, 可以使对象集合中的对象可有变化。
四、优缺点
好处:
给原来类层次增加新操作,不必修改整个类层次,只需实现一个具体访问者角色就可以,这样符合开闭原则的要求。
每个具体的访问者角色都对应一个相关操作,因此如果一个操作需求有变,那么仅修改一个具体访问者角色,而不用改动整个类层次。
由于访问者模式为系统多提供了一层“访问者”,因此可在访问者中添加一些对元素角色的额外操作。
缺点:
开闭原则的遵循总是片面的。如果系统中类层次发生了变化,则必须修改访问者角色和每一个具体访问者角色,所以访问者角色不适合具体元素角色经常发生变化的情况。
访问者角色要执行与元素角色相关操作,就必须让元素角色将内部属性暴露出来,这就意味着其它对象也可访问,这破坏了元素角色的封装性。
在访问者模式中,元素与访问者之间能够传递的信息有限,这往往也会限制访问者模式的使用。
五、适用场景
1、需要对一个对象结构中的对象进行很多不同的且不相关的操作,为了避免让这些操作破坏这些对象的类。Visitor可将相关操作集中起来定义在一个类中。
2、当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
3、对于某对象结构中各元素的操作,如果需要在不修改各元素类的前提下定义作用于这些元素的新操作,也就是动态的增加新的方法可考虑访问者模式。
4、一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。

分享到:
评论

相关推荐

    设计模式可复用面向对象软件的基础.zip

    5.11 VISITOR(访问者)—对象行为型 模式 218 5.12 行为模式的讨论 228 5.12 1 封装变化 228 5.12.2 对象作为参数 228 5.12.3 通信应该被封装还是被分布 229 5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第6...

    设计模式代码——c#

    C#设计模式(23种设计模式) 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式...22. 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)

    design-pattern-java.pdf

    模板方法模式-Template Method Pattern 模板方法模式深度解析(一) 模板方法模式深度解析(二) 模板方法模式深度解析(三) 访问者模式-Visitor Pattern 操作复杂对象结构——访问者模式(一) 操作复杂对象结构...

    深入浅出设计模式(中文版)

    5.11VisitorPattern(访问者模式) 280 5.11.1定义 280 5.11.2现实例子——收银员收银计费 282 5.11.3C#实例——人事评估 283 5.11.4Java实例——维修工程师检查车辆 287 5.11.5优势和缺陷 291 5.11.6应用情??...

    深入浅出设计模式(中文版电子版)

    5.11VisitorPattern(访问者模式) 280 5.11.1定义 280 5.11.2现实例子——收银员收银计费 282 5.11.3C#实例——人事评估 283 5.11.4Java实例——维修工程师检查车辆 287 5.11.5优势和缺陷 291 5.11.6应用情??...

    设计模式--可复用面向对象软件的基础

    5.11 VISITOR(访问者)——对象行为型模式 5.12 行为模式的讨论 第六章 结论 6.1 设计模式将带来什么 6.2 一套通用的设计词汇 6.3 书写文档和学习的辅助手段 6.4 现有方法的一种补充 6.5 重构的目标 6.6 本书简史 ...

    C#23种设计模式_示例源代码及PDF

    迭代子模式: 迭代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多 迭代子模式 个对象聚在一起形成的总体称之为聚集, 聚集对象是能够包容一组对象的容器对象。 迭代 子 模式将迭代逻辑封装到一个...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷6

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    C#23种设计模式

    │ │ └─C#设计模式(6)——原型模式(Prototype Patt O技术博客_files │ └─PrototypePattern │ ├─bin │ │ └─Debug │ ├─obj │ │ └─Debug │ │ └─TempPE │ └─Properties ├─07.Adapter...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷8

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷3

    pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/mediator //13.10中介者模式 pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷10

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷5

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷1

    pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/mediator //13.10中介者模式 pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷2

    pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/mediator //13.10中介者模式 pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷7

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷9

    pattern/src/behavior/command //13.6命令模式 pattern/src/behavior/memento //13.7备忘录模式 pattern/src/behavior/state //13.8状态模式 pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/...

    java高手真经 (UML建模+设计模式+面向服务架构) 卷4

    pattern/src/behavior/visitor //13.9访问者模式 pattern/src/behavior/mediator //13.10中介者模式 pattern/src/behavior/interpreter //13.11解释器模式 (4)SOA(12个程序包) soa/JAXWSHelloWorldServer.zip...

    asp.net知识库

    DbHelperV2 - Teddy的通用数据库访问组件设计和思考 也论该不该在项目中使用存储过程代替SQL语句 如何使数据库中的表更有弹性,更易于扩展 存储过程——天使还是魔鬼 如何获取MSSQLServer,Oracel,Access中的数据字典...

    antlr4权威指南

    取而代之的是一些广为人知的设计模式,如访问者模式。这意味着,在学会了ANTLR语法之后,你就可以重回自己熟悉的Java领域来实现真正的语言类应用程序。  ANTLR 3的LL(*)语法分析策略不如ANTLR 4的ALL(*)强大,所以...

Global site tag (gtag.js) - Google Analytics