`
clq9761
  • 浏览: 592485 次
  • 性别: Icon_minigender_1
  • 来自: 福建
社区版块
存档分类
最新评论

访问者模式

阅读更多

  访问者模式:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的
                    前提下定义作用于这些元素的新操作。

 

  即可以在不修改已有程序结构的前提下,通过添加额外的"访问者"来完成对已有代码功能的提升。

 

 要点:


  1.访问者模式适用于数据结构相对稳定的系统,它把数据结构和作用于结构上的操作之间的
     藕合解脱开,使得操作集合可以相对自由地演化。
  2.访问者模式的目的是要把处理从数据结构分离出来。如果系统有比较稳定的数据结构,
     又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得
     算法操作的增加变得容易。
  3.访问者模式的优点就是增加新的操作容易,因为增加新的操作就意味着增加一个新的访问方法。
     访问者模式将有关的行为集中到一个访问者对象中。
  4.访问者模式的缺点其实也就是使增加新的数据结构变得困难了。大多时候并不需要访问者模式,
     但当一旦需要访问者模式时,那就是真的需要它了。事实上很难找到数据结构不变化的情况,
     所以用访问者模式的机会就不太多了。

 

 

/**
 * 访问者角色类:为该对象结构中具体元素角色声明一个访问操作接口。
 * 			该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。
 * 			这样访问者就可以通过该元素角色的特定接口直接访问它。
 */
public abstract class Visitor {
	
	public abstract void visitConcreteElementA(ConcreteElementA elementA);
	
	public abstract void visitConcreteElementB(ConcreteElementB elementB);
	
	public abstract String getName();

}

 

/**
 *  具体访问者角色:实现每个由访问者角色(Visitor)声明的操作。
 */
public class ConcreteVisitor1 extends Visitor{

	@Override
	public void visitConcreteElementA(ConcreteElementA elementA) {
		
		System.out.println(elementA.getName()+" 被 "+this.getName()+" 访问。");
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB elementB) {
		
		System.out.println(elementB.getName()+" 被 "+this.getName()+" 访问。");
	}

	@Override
	public String getName() {
		return "visitor1";
	}
}

 

/**
 *  具体访问者角色:实现每个由访问者角色(Visitor)声明的操作。
 */
public class ConcreteVisitor2 extends Visitor{

	@Override
	public void visitConcreteElementA(ConcreteElementA elementA) {
		
		System.out.println(elementA.getName()+" 被 "+this.getName()+" 访问。");
	}

	@Override
	public void visitConcreteElementB(ConcreteElementB elementB) {
		
		System.out.println(elementB.getName()+" 被 "+this.getName()+" 访问。");
	}

	@Override
	public String getName() {
		return "visitor2";
	}
}

 

/**
 * Element类,定义一个accept操作,以一个访问者为参数。
 */
public abstract class Element {
	
	public abstract void accept(Visitor visitor);
	
	public abstract String getName();
}

 

/**
 * 具体元素类A,实现accept操作。
 */
public class ConcreteElementA extends Element{

	@Override
	public void accept(Visitor visitor) {
		
		// 充分利用双分派技术,实现处理与数据结构的分离
		visitor.visitConcreteElementA(this);
	}
	// 其它的相关方法
	public void operaitonA(){
		
	}
	@Override
	public String getName() {
		return "elementA";
	}
}

 

/**
 * 具体元素类B,实现accept操作。
 */
public class ConcreteElementB extends Element{

	@Override
	public void accept(Visitor visitor) {
		
		// 充分利用双分派技术,实现处理与数据结构的分离
		visitor.visitConcreteElementB(this);
	}
	// 其它的相关方法
	public void operaitonA(){
		
	}
	@Override
	public String getName() {
		return "elementB";
	}
}

 

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

	private List<Element> elements = new ArrayList<Element>();
	
	// 增加
	public void attach(Element element){
		elements.add(element);
	}
	
	// 移除
	public void detach(Element element){
		elements.remove(element);
	}
	
	// 查看显示
	public void accept(Visitor visitor){		
		// 遍历调用
		for(Element element:elements){
			element.accept(visitor);
		}
	}
}

 

public class Main {

	public static void main(String[] args) {
		
		ObjectStructure o = new ObjectStructure();
		o.attach(new ConcreteElementA());
		o.attach(new ConcreteElementB());		
		
		ConcreteVisitor1 v1 = new ConcreteVisitor1();
		ConcreteVisitor2 v2 = new ConcreteVisitor2();
		
		o.accept(v1);
		o.accept(v2);		
	}
}

 

输出结果如下:

elementA 被 visitor1 访问。
elementB 被 visitor1 访问。
elementA 被 visitor2 访问。
elementB 被 visitor2 访问。

 

 

访问者模式实例:(男人和女人不同状态下的反应)

 

 

/**
 * 状态抽象类,人只分为男人和女人,性别的分类是稳定的,所以可以在状态类中,增加
 * "男人反应"和"女人反应"两个方法,方法个数是稳定的,不会很容易的发生变化。
 */
public abstract class Action {

	// 得到男人的结论或反应
	public abstract void getManConclusion(PersonMan man);
	
	// 得到女人的结论或反应
	public abstract void getWomanConclusion(PersonWoman woman);
	
	// 获取状态名称
	public abstract String  getName();
}

 

/**
 * 成功状态,每一种具体的状态都继承"状态"抽象类,实现两个反应的方法。
 */
public class ActionSuccess extends Action{

	@Override
	public void getManConclusion(PersonMan man) {
		System.out.println(man.getName()+" "+this.getName()
				+" 时,背后多半有一个伟大的女人。");
	}

	@Override
	public void getWomanConclusion(PersonWoman woman) {
		System.out.println(woman.getName()+" "+this.getName()
				+" 时,背后多半有一个不成功的男人。");
	}

	@Override
	public String getName() {
		return "成功";
	}
}

 

/**
 * 失败状态,每一种具体的状态都继承"状态"抽象类,实现两个反应的方法。
 */
public class ActionFail extends Action{

	@Override
	public void getManConclusion(PersonMan man) {
		System.out.println(man.getName()+" "+this.getName()
				+" 时,闷头喝酒,谁也不用劝。");
	}

	@Override
	public void getWomanConclusion(PersonWoman woman) {
		System.out.println(woman.getName()+" "+this.getName()
				+" 时,眼泪汪汪,谁也劝不了。");
	}

	@Override
	public String getName() {
		return "失败";
	}
}

 

/**
 * 恋爱状态,每一种具体的状态都继承"状态"抽象类,实现两个反应的方法。
 */
public class ActionLove extends Action{

	@Override
	public void getManConclusion(PersonMan man) {
		System.out.println(man.getName()+" "+this.getName()
				+" 时,凡事不懂也要装懂。");
	}

	@Override
	public void getWomanConclusion(PersonWoman woman) {
		System.out.println(woman.getName()+" "+this.getName()
				+" 时,遇事懂也装作不懂。");
	}

	@Override
	public String getName() {
		return "恋爱";
	}
}

 

/**
 * 人的抽象类
 */
public abstract class Person {
	
	// 接受抽象方法,vistor是用来获得"状态"对象的
	public abstract void accept(Action vistor);
	
	// 获取人的类别名称
	public abstract String getName();

}

 

/**
 * 男人类
 */
public class PersonMan extends Person{

	
	@Override
	public void accept(Action vistor) {		
		
		/** 1.首先在客户程序中将具体状态作为参数传递给"男人"类完成了一次分派,
		 * 	然后"男人"类调用作为参数的"具体状态"中的方法的"男人反应",同时将自己(this)作为参数传递进去,
		 * 	这便完成了第二次分派。
		 *  2.双分派意味着得到执行的操作决定于请求的种类和两个接收者的类型,"接受"方法得到执行的操作
		 *  不仅决定于"状态"类的具体状态,还决定于它访问的'人'的类别。
		 */
		vistor.getManConclusion(this);
	}

	@Override
	public String getName() {
		return "男人";
	}
}

 

/**
 * 女人类
 */
public class PersonWoman extends Person{

	@Override
	public void accept(Action vistor) {		
		vistor.getWomanConclusion(this);
	}

	@Override
	public String getName() {
		return "女人";
	}
}

 

/**
 * 对象结构类,针对不同的"状态"遍历"男人"和"女人",得到不同的反应。
 */
public class ObjectStructure {

	private List<Person> persons = new ArrayList<Person>();
	
	// 增加
	public void attach(Person person){
		persons.add(person);
	}
	
	// 移除
	public void detach(Person person){
		persons.remove(person);
	}
	
	// 查看显示
	public void display(Action visitor){		
		// 遍历调用
		for(Person person:persons){
			person.accept(visitor);
		}
	}
}

 

public class Main {

	public static void main(String[] args) {
		
		// 在对象结构中加入到对比的男人和女人
		ObjectStructure o = new ObjectStructure();
		o.attach(new PersonMan());
		o.attach(new PersonWoman());
		
		// 成功状态下男人和女人的反应
		ActionSuccess success = new ActionSuccess();
		o.display(success);
		
		// 失败状态下男人和女人的反应
		ActionFail fail = new ActionFail();
		o.display(fail);
		
		// 恋爱状态下男人和女人的反应
		ActionLove love = new ActionLove();
		o.display(love);

	}
}

 

 

输出结果如下:

 

男人 成功 时,背后多半有一个伟大的女人。
女人 成功 时,背后多半有一个不成功的男人。
男人 失败 时,闷头喝酒,谁也不用劝。
女人 失败 时,眼泪汪汪,谁也劝不了。
男人 恋爱 时,凡事不懂也要装懂。
女人 恋爱 时,遇事懂也装作不懂。

 

  • 大小: 185.9 KB
  • 大小: 62.3 KB
分享到:
评论

相关推荐

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

    访问者模式(Visitor)是一种行为设计模式,它允许在不修改对象结构的前提下向对象结构中的元素添加新的操作。这种模式将算法与数据结构分离,使得算法可以独立于数据结构进行变化,增强了系统的可扩展性。 在C++中...

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

    《访问者模式在实际开发中的应用深度解析》 访问者模式是设计模式中的一种行为模式,它在实际的软件开发中具有重要的应用价值。通过理解并掌握访问者模式,开发者可以更好地实现对象结构中元素的操作,同时保持元素...

    设计模式 访问者模式

    **访问者模式**是一种行为设计模式,它允许在不修改对象结构的情况下添加新的操作。这种模式主要用于处理具有复杂对象结构的情况,使得我们可以对结构中的每个元素执行特定操作,而无需暴露其内部实现。 访问者模式...

    访问者模式Demo

    **访问者模式**是一种设计模式,它在软件工程中用于在不修改对象结构的前提下,为对象添加新的操作或行为。这种模式将数据结构与数据操作分离,使得可以在不改变对象本身的情况下扩展其功能。访问者模式是行为设计...

    访问者模式代码

    访问者模式是一种设计模式,属于行为模式类别,其主要目的是在不修改对象结构的前提下,为对象结构中的元素提供新的操作。这种模式的核心思想是将数据结构与数据操作分离,使得增加新的操作变得容易,同时也避免了对...

    设计模式 - 访问者模式

    **访问者模式** 访问者模式(Visitor Pattern)是一种行为设计模式,它使你能在不修改对象结构的前提下向其添加新的操作。这种模式常用于处理具有相同接口或抽象类的对象结构,使得可以在不改变原有结构的基础上...

    访问者模式例子2

    访问者模式是一种设计模式,它在对象结构中定义了一个访问并操作其元素的接口。这种模式主要用于在不改变对象结构的前提下增加对象的功能。在“访问者模式例子2”中,我们将深入探讨如何利用该模式来扩展系统的行为...

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

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

    访问者模式例子

    访问者模式是一种设计模式,属于行为模式类别,它在软件工程中被用来分离对象结构与对这个结构进行操作的行为。这种模式的主要目的是使代码结构更加灵活,同时增加新的操作而无需修改现有对象结构。在“访问者模式”...

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

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该访问者可以访问该结构中的每一个元素,同时不影响对象结构本身。这种模式的主要目的是将数据操作与数据结构分离,使得数据结构的变化...

    设计模式之访问者模式

    访问者模式是一种软件设计模式,它在对象结构中定义了一个访问者的接口,使得该访问者可以访问该结构中的每一个元素,同时不影响这些元素自身的行为。这种模式的主要目的是将数据操作和业务逻辑分离,使得数据结构...

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

    **访问者模式(Visitor)详解** 访问者模式是一种行为设计模式,它使你可以在不修改对象结构的情况下,为对象添加新的操作。这种模式的核心在于将数据结构与对这些数据的操作解耦,使得增加新的操作变得容易,同时...

    java设计模式之访问者模式

    访问者模式是一种软件设计模式,它允许在不改变对象结构的情况下,在对象的现有结构上增加新的操作。在Java中,这种模式尤其有用,因为它能够帮助我们保持类的封装性,同时提供了一种灵活的方式来扩展对象的功能。...

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

    **访问者模式详解** 访问者模式是一种行为设计模式,它允许在不修改对象结构的情况下向对象添加新的操作。这种模式的核心思想是将数据结构与算法分离,使得算法可以在不改变对象结构的前提下增加对对象的操作。 在...

    Objective C 访问者模式设计源码

    访问者模式是一种软件设计模式,属于行为模式范畴,它的核心思想是将数据结构与数据操作分离,使得在不修改原有对象结构的情况下,可以为对象添加新的操作。这种模式常用于处理具有复杂对象结构且需要对这些对象进行...

    设计模式之访问者模式Java版本实现

    **访问者模式**是软件设计模式中的一种结构型模式,它允许在不修改对象结构的情况下,在对象上增加新的操作。这种模式将数据结构与数据操作分离,使得代码更易于维护和扩展。 在Java中实现访问者模式,通常包括以下...

    设计模式之访问者模式(Visitor Pattern)

    **访问者模式(Visitor Pattern)**是一种行为设计模式,它提供了一种在不修改对象结构的情况下增加新操作的方法。这种模式的主要思想是将数据结构与算法分离,使得算法可以在不改变对象结构的情况下独立变化。 在...

    uml 文档 访问者模式

    访问者模式是一种设计模式,主要用于在不修改原有类层次结构的基础上,增加新的操作或功能。在UML(统一建模语言)文档中,访问者模式通常用于表示对象结构中的类如何接受并处理来自访问者的访问请求。这个模式的...

Global site tag (gtag.js) - Google Analytics