- 浏览: 67969 次
- 性别:
- 来自: 上海
最新评论
-
java苹果+番茄:
已经修改,感谢大家提的意见;有一年多没进来了,很惭愧;以后一定 ...
java设计模式笔记链接地址汇总 -
youthon:
命令(Command)模式【行为模式第九篇】的链接应为http ...
java设计模式笔记链接地址汇总 -
youthon:
你给的链接只有你自己才能打开,你改改吧
java设计模式笔记链接地址汇总 -
shaozhi_jinni:
[b][/b][i][/i][u][/u]引用引用
[img ...
模板方法(Template Method)模式【行为模式第十篇】 -
Tank03:
慢慢的走~
android开发学习中(已经学会了几个小玩意),兴趣大增
访问者(Visitor)模式:
访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作要修改的话,接受这个操作的数据
结构则 可以保持不变。
聚集是的大多数的系统都要处理一种容器对象,它保存了对其他对象的引用。相信大多数读者都有处理聚集的经验,但是人家处理过的大多数聚集
恐怕 都是同类操作,而迭代子模式就是为这种情况准备的设计模式。
如果需要针对一个包含不同类型元素的聚集采取某种操作,而操作的细节根据元素的类型不同而有所不同时,就会出现必须对元素类型做类型判断
的条件转移语句。
一、访问者模式涉及到抽象访问者角色、具体访问者角色、抽象节点角色、具体节点角色、结构对象角色以及客户端角色。
1、抽象访问者角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
2、具体访问者角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
3、抽象节点角色:声明一个接受操作,接受一个访问者对象作为一个参量。
4、具体节点角色:实现了抽象元素所规定的接受操作。
5、结构对象角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素
如果需要,可以设计成一个复合对象或者一个聚集。
二、访问者模式仅应当在被访问的类结构非常稳定的情况下使用。换言之,系统很少出现需要加入新节点的情况。如果出现需要加入的新节点
这时就必须在每一个访问对象里加入一个对应于这个新节点的访问操作,而这是对一个系统的大规模修改,因而是违背“开闭”原则的。
访问这模式允许在节点中加入新的方法,相应的仅仅需要在一个新的访问者类中加入此方法,而不需要在每一个访问者类中都加入此方法。
显然,访问者模式提供了倾斜的可扩展性设计:方法集合的可扩展性和类集合的不可扩展性。
换言之,如果系统的数据结构是濒繁变化的,则不适合使用访问者模式。
三、使用访问者模式的优缺点:
1、优点:
(1)访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加
新的操作会很复杂。而使用访问者模式,增加新的操作己意味这增加一个新的访问者类,因此,变得很容易。
(2)访问者模式将有关的行为几种到一个访问者对象中,而不是分散到一个个的节点类中。
(3)访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构
的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
(4)积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己
内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。
2、缺点:
(1)增加新的节点类变得很困难。没增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个
具体访问者类中增加相应的具体操作。
(2)破坏封装。访问者模式要求访问者对象并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须
暴露一些自己的操作和内部状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。
当实现访问者模式时,要将尽可能多的对象浏览逻辑放在(抽象访问者)Visitor类中,而不是放在它的子类里。
这样的话,具体访问者类对所有的对象结构依赖较少,从而使维护较为容易。
负责遍历行为的,可供选择的有:结构对象、访问者对象或者创建一个新的迭代对象。
(1)由结构对象负责迭代是最常见的选择,这也就是需要结构对象角色的出发点。
(2)另一个解决方案是使用一个迭代对象来负责遍历行为。
(3)将遍历行为放到访问者中是第三个可能的选择。一般而言,这样做会导致每一个具体访问者都不得不具有管理聚集
的内部功能,而这在一般情况下是不理想的。然而如果遍历的逻辑较为复杂的话,将所有的遍历逻辑方到结构对象
角色中,不如这种做法也不失为一种可行的选择。
访问者模式是对象的行为模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作要修改的话,接受这个操作的数据
结构则 可以保持不变。
聚集是的大多数的系统都要处理一种容器对象,它保存了对其他对象的引用。相信大多数读者都有处理聚集的经验,但是人家处理过的大多数聚集
恐怕 都是同类操作,而迭代子模式就是为这种情况准备的设计模式。
如果需要针对一个包含不同类型元素的聚集采取某种操作,而操作的细节根据元素的类型不同而有所不同时,就会出现必须对元素类型做类型判断
的条件转移语句。
一、访问者模式涉及到抽象访问者角色、具体访问者角色、抽象节点角色、具体节点角色、结构对象角色以及客户端角色。
1、抽象访问者角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。
2、具体访问者角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。
3、抽象节点角色:声明一个接受操作,接受一个访问者对象作为一个参量。
4、具体节点角色:实现了抽象元素所规定的接受操作。
5、结构对象角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素
如果需要,可以设计成一个复合对象或者一个聚集。
//抽象访问者角色 public interface Visitor{ //对于NodeA的访问操作 void visit(NodeA node); //对于NodeB的访问操作 void visit(NodeB node); } //具体访问者角色 public class VisitorA implements Visitor{ //对应于NodeA的访问操作 public void visit(NodeA nodeA){ System.out.println(nodeA.operationA()); } //对应于NodeB的访问操作 public void visit(NodeB nodeB){ System.out.println(nodeB.operationB()); } } public class VisitorB implements Visitor{ //对应于NodeA的访问操作 public void visit(NodeA nodeA){ System.out.println(nodeA.operationA()); } //对应于NodeB的访问操作 public void visit(NodeB nodeB){ System.out.println(nodeB.operationB()); } } //抽象节点角色 public abstract class Node{ //接受操作 public abstract void accept(Visitor visitor); } //模式中具体节点NodeA角色 public class NodeA extends Node{ //接受操作 public void accept(Visitor visitor){ visitor.visit(this); } //NodeA特有的商业方法 public String operationA(){ return "NodeA is visited."; } } public class NodeB extends Node{ //接受操作 public void accept(Visitor visitor){ visitor.visit(this); } //NodeA特有的商业方法 public String operationB(){ return "NodeB is visited."; } } //模式中结构对象ObjectStructure import java.util.Vector; import java.util.Enumeration; public class ObjectStructure{ private Vector nodes; private Node node; public ObjectStructure(){ nodes = new Vector(); } //执行访问操作 public void action(Visitor visitor){ for(Enumeration e = nodes.elements(); e.hasMoreElements();){ node = (Node)e.nextElement(); node.accept(visitor); } } //增加一个新的元素 public void add(Node node){ nodes.addElements(node); } } //客户端 public class Client{ private static ObjectStructure aObjects; private static Visitor visitor; public static void main(String args[]){ //创建一个结构对象 aObjects = new ObjectStruture(); //给结构增加一个节点 aObjects.add(new NodeA()); //给结构增加一个节点 aObjects.add(new NodeB()); //创建一个新的访问者 visitor = new VisitorA(); //让访问者访问结构 aObjects.action(visitor); } }
二、访问者模式仅应当在被访问的类结构非常稳定的情况下使用。换言之,系统很少出现需要加入新节点的情况。如果出现需要加入的新节点
这时就必须在每一个访问对象里加入一个对应于这个新节点的访问操作,而这是对一个系统的大规模修改,因而是违背“开闭”原则的。
访问这模式允许在节点中加入新的方法,相应的仅仅需要在一个新的访问者类中加入此方法,而不需要在每一个访问者类中都加入此方法。
显然,访问者模式提供了倾斜的可扩展性设计:方法集合的可扩展性和类集合的不可扩展性。
换言之,如果系统的数据结构是濒繁变化的,则不适合使用访问者模式。
三、使用访问者模式的优缺点:
1、优点:
(1)访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加
新的操作会很复杂。而使用访问者模式,增加新的操作己意味这增加一个新的访问者类,因此,变得很容易。
(2)访问者模式将有关的行为几种到一个访问者对象中,而不是分散到一个个的节点类中。
(3)访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构
的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
(4)积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己
内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。
2、缺点:
(1)增加新的节点类变得很困难。没增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个
具体访问者类中增加相应的具体操作。
(2)破坏封装。访问者模式要求访问者对象并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须
暴露一些自己的操作和内部状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。
当实现访问者模式时,要将尽可能多的对象浏览逻辑放在(抽象访问者)Visitor类中,而不是放在它的子类里。
这样的话,具体访问者类对所有的对象结构依赖较少,从而使维护较为容易。
负责遍历行为的,可供选择的有:结构对象、访问者对象或者创建一个新的迭代对象。
(1)由结构对象负责迭代是最常见的选择,这也就是需要结构对象角色的出发点。
(2)另一个解决方案是使用一个迭代对象来负责遍历行为。
(3)将遍历行为放到访问者中是第三个可能的选择。一般而言,这样做会导致每一个具体访问者都不得不具有管理聚集
的内部功能,而这在一般情况下是不理想的。然而如果遍历的逻辑较为复杂的话,将所有的遍历逻辑方到结构对象
角色中,不如这种做法也不失为一种可行的选择。
//一个电脑专卖系统 //抽象访问者角色 public abstract class Visitor{ public abstract void visitHardDisk(HardDisk e); public abstract void visitMainBoard(MainBoard e); public abstract void visitCpu(Cpu e); public abstract void visitPc(Pc e); public abstract void visitCase(Case e); public abstract void visitIntegratedBoard(IntegratedBoard e); } //具体访问者角色 public class PriceVisitor extends Visitor{ private float total; public PriceVisitor(){ total = 0; } public float value(){ return total; } public void visitHardDisk(HardDisk e){ total += e.price(); } public void visitMainBoard(MainBoard e){ total += e.price(); } public void visitCpu(Cpu e){ total += e.price(); } public void visitPc(Pc e){ total += e,price(); } public void visitCase(Case e){ total += e.price(); } public void visitIntegratedBoard(IntegratedBoard e){ total += e.price(); } } //具体访问角色 import java.util.Vector; public class InventoryVisitor extends Visitor{ private Vector inv; public InventoryVisitor(){ inv = new Vector(10.5); } public int size(){ return inv.size(); } public void visitHardDisk(HardDisk e){ inv.addElement(e); } public void visitMainBoard(MainBoard e){ inv.addElement(e); } public void visitCpu(Cpu e){ inv.addElement(e); } public void visitPc(Pc e){ inv.addElement(e); } public void visitCase(Case e){ inv.addElement(e); } public void visitIntegratedBoard(IntegratedBoard e){ inv.addElement(e); } } //抽象节点角色 public abstract class Equipment{ //接受方法 public abstract void accept(Visitor vis); //商业方法 public abstract double price(); } //具体节点角色 public class MainBoard extends Equipment{ public double price(){ return 100.00; } public void accept(Visitor v){ System.out.println("MainBoard has been visited."); v.visitMainBoard(this); } } //具体节点角色 public class HardDisk extends Equipment{ public double price(){ return 200.00; } public void accept(Visitor v){ System.out.println("HardDisk has been visited."); v.visitHardDisk(this); } } //具体节点角色 public class Cpu extends Equipment{ public double price(){ return 800.00; } public void accept(Visitor v){ System.out.println("CPU has been visited."); v.visitCpu(this); } } //具体节点角色 public class Case extends Equipment{ public double price(){ return 30.00; } public void accept(Visitor v){ System.out.println("Case has been visited."); v.visitCase(this); } } //抽象复合节点 public abstract class Composite extends Equipment{ private Vector parts = new Vector(10); public Composite(){} public double price(){ double total = 0; for(int i = 0; i < parts.size(); i ++){ total += ((Equipment)parts.get(i)).price(); } return total; } public void accept(Visitor v){ for(int i = 0; i < parts.size(); i ++){ ((Equipment)parts.get(i)).accept(v); } } } //具体复合节点角色 public class IntegratedBoard extends Composite{ public IntegratedBoard(){ super.add(new MainBoard()); super.add(new Cpu()); } public void accept(Visitor v){ System.out.println("IntegratedBoard has been visited."); super.accept(v); } } //具体复合节点角色 public class Pc extends Composite{ public Pc(){ super.add(new IntegratedBoard()); super.add(new HardDisk()); super.add(new Case()); } public void accept(Visitor v){ System.out.println("Pc has been visited."); super.accept(v); } } //客户端 public class Client{ private static PriceVisitor pv; private static InventoryVisitor iv; private static Equipment equip; public static void main(String args[]){ equip = new Pc(); pv = new PriceVisitor(); equip.accept(pv); System.out.println("Price: " + pv.value()); System.out.println(); iv = new InventoryVisitor(); equip.accept(iv); System.out.println("Number of parts: " + iv.size()); } }
发表评论
-
java设计模式笔记链接地址汇总
2009-10-24 14:46 2294各位,这些笔记已经生成了pdf,如果有兴趣的可以在本文末尾下载 ... -
MVC模式【行为模式第十三篇】
2009-10-23 23:36 1517MVC模式:就是模型-视 ... -
状态(State Pattern)模式【行为模式第十二篇】
2009-10-23 23:35 1371状态(State Pattern)模式:又称为状态对象模式,状 ... -
责任链(Chain of Responsibility)模式【行为模式第十一篇】
2009-10-23 23:33 1255责任链(Chain of Responsibility)模式 ... -
模板方法(Template Method)模式【行为模式第十篇】
2009-10-23 23:32 1229模板方法(Template Method)模式 模板方法模式 ... -
命令(Command)模式【行为模式第九篇】
2009-10-23 23:31 1416命令(Command)模式: ... -
解释器(Interpreter)模式【行为模式第八篇】
2009-10-23 23:29 1111解释器(Interpreter)模 ... -
观察者(Observer)模式【行为模式第七篇】
2009-10-23 23:28 1280观察者(Observer)模式 ... -
迭代子(Iterator)模式【行为模式第五篇】
2009-10-23 23:25 1536迭代子(Iterator)模式: 迭代子模式又叫游标(Cur ... -
调停者(Mediator)模式 【行为模式第四篇】
2009-10-23 23:23 2676调停者(Mediator)模式 调停者模式是对象的行为模式。 ... -
策略(Strategy)模式 【行为模式第三篇】
2009-10-23 23:22 1541策略(Strategy)模式 策略模式属于对象的行为模式。其 ... -
不变(Immutable)模式【行为模式第二篇】
2009-10-23 23:21 1704不变(Immutable)模式 一个对象的状态在对象被创建之 ... -
备忘录(Memento Pattern)模式 【行为模式第一篇】
2009-10-23 23:19 1995备忘录(Memento Pattern)模式 备忘录模式又叫 ... -
适配器模式举例【结构模式第八篇】
2009-10-23 23:17 1056XMLProperties与适配器模式举例: //---- ... -
适配器模式【结构模式第六篇】
2009-10-23 23:12 1209适配器模式(Adapter Pattern)(另称-变压器模式 ... -
桥梁(Bridge)模式【结构模式第五篇】
2009-10-23 23:09 1368桥梁(Bridge)模式: 一、桥梁模式的用意 桥梁模式 ... -
门面(Facade)模式【结构模式第四篇】
2009-10-23 23:08 1240门面(Facade)模式: 是对象的结构模式。外部与一个子系 ... -
亨元(Flyweight Pattern)模式【结构模式第三篇】
2009-10-23 23:07 1189亨元(Flyweight Pattern) ... -
合成(Composite)模型模式【结构模式第二篇】
2009-10-23 23:04 1400合成(Composite)模型模式: 属于对象的结构模式,有 ... -
代理(Proxy)模式 【结构模式第一篇】
2009-10-23 23:02 1408代理(Proxy)模式 是对 ...
相关推荐
创建型: 1. 单件模式(Singleton Pattern) 2. 抽象工厂(Abstract Factory) 3. 建造者模式(Builder) 4. 工厂方法模式(Factory Method) 5.... 访问者模式(Visitor Pattern) 23. 状态模式(State Pattern)
第26章 访问者模式(Visitor) 26.1 模式解说 26.2 结构与用法 26.2.1 模式结构 26.2.2 代码模板 26.2.3 问题讨论 26.3 范例与实践 26.3.1 访问者模式在薪酬福利管理中的应用 26.3.2 范例小结 主要参考文献
3. **行为型模式**:包括策略(Strategy)、模板方法(Template Method)、观察者(Observer)、迭代器(Iterator)、访问者(Visitor)、责任链(Chain of Responsibility)、命令(Command)、备忘录(Memento)、...
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...
第26章 访问者模式(Visitor) 26.1 模式解说 26.2 结构与用法 26.2.1 模式结构 26.2.2 代码模板 26.2.3 问题讨论 26.3 范例与实践 26.3.1 访问者模式在薪酬福利管理中的应用 26.3.2 范例小结 ...
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...
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 总结 ...
7. 访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 本书的末尾还介绍了混编模式,即在实际应用中将多种模式组合...
行为型设计模式如策略(Strategy)、模板方法(Template Method)、观察者(Observer)、命令(Command)、迭代器(Iterator)、访问者(Visitor)、状态(State)、职责链(Chain of Responsibility)、解释器...
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...
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...
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...
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...
行为模式 13、CHAIN OF RESPONSIBLEITY —晚上去上英语课,为了好开溜坐到了最后一排,哇,前面 、 坐了好几个漂亮的 MM 哎, 找张纸条, 写上“Hi,可以做我的女朋友吗?如果不愿意请向前传”, 纸条就一个接一...
20. 访问者模式(Visitor Pattern):表示一个作用于某对象结构中的各元素的操作,使得可以在不改变该对象结构的前提下定义新的操作。 21. 状态模式(State Pattern):允许一个对象在其内部状态改变时改变其行为,...
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...
4. **行为型模式**:如策略模式(Strategy)、模板方法模式(Template Method)、观察者模式(Observer)、命令模式(Command)、迭代器模式(Iterator)、访问者模式(Visitor)、责任链模式(Chain of ...
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...
如适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)、解释器模式(Interpreter)...Strategy)、模板方法模式(Template Method)、访问者模式(Visitor)等...