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

理解访问者模式

阅读更多

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

  先看维基的描述:

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

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

   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
分享到:
评论

相关推荐

    设计模式C++学习之访问者模式(Visitor)

    在`Demo18_Visitor`中,我们可以看到一个具体的访问者模式实现示例,通过阅读源代码,可以更好地理解访问者模式的运作机制。代码通常会展示如何定义和使用访问者接口,以及如何在元素类中调用`accept`方法以执行特定...

    设计模式-访问者模式(讲解及其实现代码)

    而`code`文件夹中则可能包含了上述步骤的示例代码,你可以通过查看这些代码来更深入地理解访问者模式的应用。 总的来说,访问者模式是一种在不修改原有系统结构的基础上,增加新功能的有效设计模式。在处理具有复杂...

    访问者模式代码示例

    访问者模式是一种设计模式,属于行为模式类别,它在对象结构中定义了一个访问路径,使得这个访问者...通过分析提供的代码示例,我们可以深入理解访问者模式的实现细节和应用场景,进一步提升我们的编程技巧和设计能力。

    28访问者模式.zip

    首先,让我们理解访问者模式的基本组成: 1. **元素接口(Element Interface)**:定义一个接受访问者的接口,通常包含一个accept方法,该方法接收一个访问者对象作为参数。 2. **具体元素(Concrete Element)**:...

    访问者模式在实际开发中的Demo

    通过理解并掌握访问者模式,开发者可以更好地实现对象结构中元素的操作,同时保持元素类的封装性,避免因频繁修改而引入的复杂性。本文将深入探讨访问者模式的概念、结构以及在实际开发中的应用实例。 访问者模式的...

    3 访问者模式-课程内容.rar

    《访问者模式详解》 ...通过学习,读者不仅可以理解访问者模式的基本概念,还能掌握如何在实际项目中应用该模式,提高代码的可维护性和扩展性。对于想要提升设计能力的开发者来说,这是一个不可多得的学习资源。

    访问者模式

    ### 访问者模式详解 ...通过以上步骤,我们能够清晰地理解访问者模式的实现过程以及其实现背后的逻辑。访问者模式在软件工程中有着广泛的应用,特别是在需要灵活扩展系统功能而无需修改现有代码的情况下。

    设计模式 访问者模式

    **访问者模式**是一种行为设计模式,它允许在不修改对象结构的情况下添加新的操作。这种模式主要用于处理具有复杂对象结构的情况...在理解并掌握访问者模式后,我们可以更有效地应对那些需要频繁增加新操作的复杂系统。

    设计模式的访问者模式的例子

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该..."设计模式的访问者模式的例子"是理解并掌握这一模式的好材料,对于想要深入学习设计模式的IT从业者而言,这是一个不容忽视的学习资源。

    访问者模式代码

    访问者模式是一种设计模式,属于行为模式类别,其主要目的是在不修改对象结构的前提下,为对象结构中的元素提供新的操作。...通过理解并运用访问者模式,我们可以编写出更加灵活、易于维护的代码。

    访问者模式例子

    在“访问者模式”的例子中,我们将深入理解其核心概念和应用场景。 访问者模式的核心组件包括: 1. **元素(Element)接口/抽象类**:这是对象结构中的基本组成单元,定义了一个接受访问者的接口。 2. **具体元素...

    68丨访问者模式(上):手把手带你还原访问者模式诞生的思维过程1

    【访问者模式】是一种行为设计模式,其主要目的是在不修改已有对象结构的前提下,为对象增加新的操作。这种模式在23种经典设计模式中属于较为复杂的一种,因为它的理解和应用相对困难,可能导致代码可读性和可维护性...

    Objective C 访问者模式设计源码

    访问者模式是一种软件设计模式,属于行为模式范畴,它的核心思想是将数据结构与数据操作分离,使得在不修改原有对象结构的情况下,可以为对象...理解并熟练应用访问者模式,能够帮助我们编写出更灵活、可维护的代码。

    深入浅出Java的访问者模式

    【访问者模式】是一种设计模式,它允许在不修改对象结构的情况下增加新的操作。这种模式在Java等面向对象编程语言中被广泛应用,特别是在处理复杂的类层次结构时,以应对不断变化的需求。 【定义】访问者模式的核心...

    设计模式系列之visitor

    压缩包中的"visitor"文件可能包含对该模式的详细代码示例、讲解文档或者案例分析,供学习者深入理解访问者模式的工作原理和实际应用。通过阅读这些材料,你可以更全面地掌握这一设计模式,以便在未来开发中灵活运用...

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

    3. **增加复杂性**:如果对象结构过于复杂,访问者模式会增加系统的理解难度。 在给出的`VisitorPattern.cpp`和`VisitorPattern.h`文件中,我们可以看到实现访问者模式的具体代码。通常,`VisitorPattern.cpp`会...

    C++设计模式课件24_Vistor_访问器.pdf

    ### C++设计模式之访问者(Vistor)模式解析 #### 概述 在软件开发领域,设计模式作为解决特定问题的最佳实践...通过上述分析,我们可以更深入地理解访问者模式的核心思想及其应用场景,从而更好地应用于实际开发中。

    JAVA设计模式之访问者模式详解

    在Java中,理解访问者模式需要结合分派的概念。分派是指根据对象的类型选择相应的方法。分派分为静态分派和动态分派。 静态分派发生在编译时期,主要体现在方法重载上。例如,当有多个同名但参数类型不同的方法时,...

    69丨访问者模式(下):为什么支持双分派的语言不需要访问者模式?1

    【访问者模式】是一种设计模式,它允许在不修改已有类结构...理解双分派的概念有助于我们更好地认识访问者模式的作用以及它在不同语言环境下的适用性。通过深入思考和分析,我们可以提升自己的编程技能和问题解决能力。

Global site tag (gtag.js) - Google Analytics