`
pjwqq
  • 浏览: 79608 次
社区版块
存档分类
最新评论

理解访问者模式

阅读更多

  访问者模式是个有点深度的模式。

  先看维基的描述:

  访问者模式是一种将算法与对象结构分离的软件设计模式。

  这个模式的基本想法如下:

   1. 首先我们拥有一个由许多对象构成的对象结构,这些对象的类都拥有一个accept方法用来接受访问者对象;

   2.访问者是一个接口,它拥有一个visit方法,这个方法对访问到的对象结构中不同类型的元素作出不同的反应;

   3.在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施accept方法,在每一个元素的accept方法中回调访问者的visit方法,从而使访问者得以处理对象结构的每一个元素。

   4.我们可以针对对象结构设计不同的实在的访问者类来完成不同的操作。 

 

  当然还有一点作用它没提到,visitor模式可以在不改变对象结构现有类的情况下(不污染),给它们加上新的方法,不过这个不是visitor模式的重点。

 

我的理解:

  设想某个对象结构中,存在一些不同的实例,它们实现一个共同接口,而具体行为可能完全不同。如果要遍历结构中的对象,并做某种处理,恐怕要用if instanceof  来判断实例类型,再做处理,因为访问者(算法拥有者)并不知道那些对象的具体类型。如此一来,对象结构和算法就不可避免耦合。

 

  访问者模式的解决办法很简单,既然访问者无法直接判断对象结构中对象的类型,那就把对象实例作为参数传给访问者。而访问者中定义一系列重载函数,根据具体传入实例类型来分派执行。

 

  那么问题就是怎么将对象结构中的对象作为实例传递给访问者呢?

 

  最简单办法就是在遍历过程中 访问者.visit(被访问对象),简单明了。

 

  但是这样又会产生一个问题,被访问对象的类型是无需关心了,访问者对象的类型怎么办?用多个访问者处理对象结构也是很正常的事吧?

 

  无需关心被访问者类型,也无需关心访问者类型,实现完美的OCP,访问者模式提供了解决方式。换个说法叫"双重分派"  

 

自己写个Demo:




 
 

 army中有各种职业:将军,牧师,士兵,

 有2个算法基于army实现:打仗,吃饭

 

army成员:

public interface IArmy {
	public String fight();	
	public void accept(IVisitor visitor);	
}

 

public class General implements IArmy {
	private String role = "将军";
	
	private String eat = "火腿";

	public String getEat() {
		return eat;
	}

	public String getRole() {
		return role;
	}

	@Override
	public String fight() {
		return this.getRole()+":"+"给我上";		
	}

	@Override
	public void accept(IVisitor visitor) {
		visitor.visit(this);
	}

}

 

public class Minister implements IArmy {
	private String role = "牧师";
	
	private String eat = "蓝瓶";

	public String getEat() {
		return eat;
	}

	public String getRole() {
		return role;
	}
	
	@Override
	public String fight() {
		return this.getRole()+":"+"我奶";		
	}
	
	@Override
	public void accept(IVisitor visitor) {
		visitor.visit(this);
	}

}

 

public class Soldier implements IArmy {
	private String role = "士兵";
	
	private String eat = "面包";

	public String getEat() {
		return eat;
	}

	public String getRole() {
		return role;
	}
	
	@Override
	public String fight() {
		return this.getRole()+":"+"我砍";	
	}
	
	@Override
	public void accept(IVisitor visitor) {
		visitor.visit(this);
	}

}

 visitor

public interface IVisitor {
	public void visit(General general);
	public void visit(Minister minister);
	public void visit(Soldier soldier);
}

 

public class FightVisitor implements IVisitor {

	@Override
	public void visit(General general) {
		System.out.println(general.fight());
	}

	@Override
	public void visit(Minister minister) {
		System.out.println(minister.fight());	
	}

	@Override
	public void visit(Soldier soldier) {
		System.out.println(soldier.fight());	
	}

}

 

 

package vistor;

public class SupplyVisitor implements IVisitor {

	@Override
	public void visit(General general) {
		System.out.println(general.getEat());
	}

	@Override
	public void visit(Minister minister) {
		System.out.println(minister.getEat());
	}

	@Override
	public void visit(Soldier soldier) {
		System.out.println(soldier.getEat());
	}

}

 Army(对象结构):

public class Army {
	private List<IArmy> army = new ArrayList<IArmy>();
	
	public void add(IArmy member){
		this.army.add(member);
	}

	public void handleRequest(IVisitor visitor) {
		for (IArmy member : army){
			member.accept(visitor);
		}	
	}
}

 

client:

public class Client {

	public static void main(String[] args) {
		Army army = new Army();
		army.add(new General());
		army.add(new Minister());
		army.add(new Soldier());
		//补给
		army.handleRequest(new SupplyVisitor());
		//战斗
		army.handleRequest(new FightVisitor());
	}

}

 结果:

火腿
蓝瓶
面包
将军:给我上
牧师:我奶
士兵:我砍

 

这个实现过程有点象踢皮球:

    1.对象结构(army)接收访问者对象,不关心其具体类型

           public void handleRequest(IVisitor visitor){...}

    2.对象结构(army)中遍历被访问对象时,被访问对象接收访问者对象

           member.accept(visitor);

    3.被访问对象把自己作为参数交给访问者并调用访问者的方法

             public void accept(IVisitor visitor) {

  visitor.visit(this);

       }

     4.访问者对象执行算法,可以利用被访问者对象的方法,也可以自定义新方法。

              

这个模式让我有点晕天真

  • 大小: 48.7 KB
2
0
分享到:
评论

相关推荐

    访问者模式(Visitor)原理图

    访问者模式(Visitor Pattern)是GoF提出的23种设计模式中的一种,属于行为模式。它表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。从定义可以看出,...

    [行为型模式] 访问者模式的理解

    NULL 博文链接:https://jacky-dai.iteye.com/blog/2309035

    C++设计模式之访问者模式

    我也没有实战经验,对于访问者模式的理解完全来自GOF的《设计模式:可复用面向对象软件的基础》,而这篇文章就是根据对这本书的理解而写出来的。在读《设计模式:可复用面向对象软件的基础》的时候,让我想起自己做过...

    Python 如何实现访问者模式

    主要介绍了Python 如何实现访问者模式,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    设计模式课件大全

    PPT内容包括:内附代码,实例,方便理解。 继承、封装、多态、UML 设计模式02 设计模式03-创建型模式 ...设计模式16-策略模式、模板方法、访问者 此PPT实例便于理解,对于深入理解OO思想有很大帮助。

    深入浅出java设计模式(高清中文PDF)

    文件类型为PDF文件,此文档对20多种java设计模式进行了详细讲解,在中文讲解的过程中还附有代码示例给学习者进行参考,使学习者通过实践更容易理解设计模式的原理。...为了读者对访问者模式有更好的理解。

    设计模式所有实验及实验报告及代码.zip

    软件设计模式概述 2GoF 的 23 种设计模式 ...34访问者模式 35备忘录模式 36解释器模式 37UMLet的使用与类图的设计 38创建型模式应用实验 39结构型模式应用实验 40行为型模式应用实验 所有实验及实验报告及代码

    Java设计模式,并加上个人理解

    1. 设计模式 ...13. 访问者模式 (Visitor Pattern) 14. 迭代器模式 (Iterator Pattern) 15. 享元模式 (Flyweight Pattern) 16. 桥接模式 (Bridge Pattern) 17. 观察者模式 (Observer Pattern)

    java中的设计模式,主要的设计模式

    设计模式:(常用23种-----像内功心法) 1. 设计模式不是一个知识点 2. 设计模式是一种设计经验的总结 3. 设计模式是用来解决某些场景下的某一类问题-------... 命令模式、状态模式、备忘录模式、访问者模式、中介者模式

    JAVA设计模式之行为模式

    包括Template(模板模式)、Chain of Responsibility(责任链模式)、Memento(纪念品模式)、Mediator(中介模式)、Strategy(策略模式)、State 、Observer(观察者模式)、Visitor(访问模式)、Command(命令模式)的源代码,...

    研磨设计模式(完整带书签).part2.pdf

    本电子书一共两个压缩文档,本文件为part2. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。...第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    设计模式精解及面试攻略

    第6章阐释行为模式(职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者模式);第7章针对所有设计模式向初学者提供一些提示;第8章包括常见的面试问题及实际示例;第9章涵盖Java...

    尚硅谷设计模式源码笔记课件.zip

    行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...

    研磨设计模式(完整带书签).part1.pdf

    本电子书一共两个压缩文档,该文档为part1。 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。...第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    设计模式Demo

    行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。 二、设计...

    研磨设计模式-part2

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义...第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式-part4

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义...第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    研磨设计模式-part3

    完整清晰版,完美书签. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义...第25章 访问者模式(Visitor) 附录A常见面向对象设计原则 附录BUML简介 参考文献

    设计模式 GOF 23

    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...

    [Java设计模式(第2版)(Design.Patterns.in.Java).John.Metsker

    《java设计模式(第2版)》通过一个完整的java项目对经典著作design patterns一书介绍的23种设计模式进行了深入分析与讲解,实践性强,却又不失对模式本质的探讨。...第29章 访问者(visitor)模式 278

Global site tag (gtag.js) - Google Analytics