`

读《研磨设计模式》-代码笔记-访问者模式-Visitor

阅读更多
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/



import java.util.ArrayList;
import java.util.List;

interface IVisitor {
	
	//第二次分派,Visitor调用Element
	void visitConcreteElementA(ConcreteElementA elementA);
	
	void visitConcreteElementB(ConcreteElementB elementB);
	
}

/*
 * Element代表已有的功能
 * 现在要增加新的功能,由IVisitor“携带”新功能,将IVisitor传进去
 * 那IVisitor一方面可以调用Element已有的功能,一方面可定义自己的功能(新功能)
 * 达到为Element新增(扩展)功能而不改变Element的目的
 * 是为“双重分派”
 */
abstract class Element {
	
	//第一次分派,Element调用Visitor
	public abstract void accept(IVisitor visitor);
	
}


class ConcreteElementA extends Element {

	public void accept(IVisitor visitor) {
		visitor.visitConcreteElementA(this);
	}
	
	public void someExistingMethodInA() {
		System.out.println("someExistingMethodInA");
	}
}


class ConcreteElementB extends Element {

	public void accept(IVisitor visitor) {
		visitor.visitConcreteElementB(this);
	}
	
	public void someExistingMethodInB() {
		System.out.println("someExistingMethodInB");
	}
}


class ConcreteVisitor1 implements IVisitor {

	public void visitConcreteElementA(ConcreteElementA elementA) {
		System.out.println("ConcreteVisitor1 do something before elementA");
		elementA.someExistingMethodInA();
		System.out.println("ConcreteVisitor1 do something after elementA");
	}

	public void visitConcreteElementB(ConcreteElementB elementB) {
		System.out.println("ConcreteVisitor1 do something before elementB");
		elementB.someExistingMethodInB();
		System.out.println("ConcreteVisitor1 do something after elementB");
	}
	
}


//可以定义不同的Visitor,添加不同的功能
class ConcreteVisitor2 implements IVisitor {
	
	public void visitConcreteElementA(ConcreteElementA elementA) {
		System.out.println("ConcreteVisitor2 do something before elementA");
		elementA.someExistingMethodInA();
		System.out.println("ConcreteVisitor2 do something after elementA");
	}
	
	public void visitConcreteElementB(ConcreteElementB elementB) {
		System.out.println("ConcreteVisitor2 do something before elementB");
		elementB.someExistingMethodInB();
		System.out.println("ConcreteVisitor2 do something after elementB");
	}
	
}


//访问者是给一系列对象添加功能的,因此要遍历一系列对象,定义一个ObjectStructure来辅助实现
class ObjectStructure {
	
	private List<Element> elementList = new ArrayList<Element>();
	
	public void handleRequest(IVisitor visitor) {
		for (Element element : elementList) {
			element.accept(visitor);
		}
	}
	
	public void addElement(Element element) {
		this.elementList.add(element);
	}
}



/**
 * 扩展:
 * 利用组合模式和访问者模式,实现以下功能:
 * 1、输出元素的名字
 * 2、在组合元素对象前加上“节点:”,在叶子元素对象前加上“叶子:”
 */
interface IVisitorr {
	
	void visitComposite(Compositee composite);
	
	void visitLeaf(Leaff leaf);
	
}


abstract class Componentt {
	
	abstract void accept(IVisitorr visitor);
	
	//叶子元素不重写这些方法,表示不支持这些功能
	public void addChild(Componentt component) {
		throw new UnsupportedOperationException("对象不支持这个功能");
	}
	
	public void removeChild(Componentt component) {
		throw new UnsupportedOperationException("对象不支持这个功能");
	}
	
	public void getChild(int index) {
		throw new UnsupportedOperationException("对象不支持这个功能");
	}
}


class Compositee extends Componentt {

	private String name;
	private List<Componentt> childComponents = new ArrayList<Componentt>();
	
	public Compositee(String name) {
		this.name = name;
	}
	
	void accept(IVisitorr visitor) {
		visitor.visitComposite(this);
		//让访问者也访问子元素
		for (Componentt child : childComponents) {
			child.accept(visitor);
		}
	}
	
	public void addChild(Componentt component) {
		childComponents.add(component);
	}
	
	public String getName() {
		return this.name;
	}
	
}


class Leaff extends Componentt {
	
	private String name;
	
	void accept(IVisitorr visitor) {
		visitor.visitLeaf(this);
	}
	
	public Leaff(String name) {
		this.name = name;
	}
	
	public String getName() {
		return this.name;
	}
}


class PrintNameDetailVisitor implements IVisitorr {

	public void visitComposite(Compositee composite) {
		System.out.println("节点:" + composite.getName());
	}

	public void visitLeaf(Leaff leaf) {
		System.out.println("叶子:" + leaf.getName());
	}
	
}


//本来在类Composite里面已递归遍历了各元素,但为了表现Visitor模式同时为了以后更好的扩展,仍然定义一个ObjectStructure
class ObjectStructuree {
	
	private Componentt root;
	
	public void handleRequest(IVisitorr visitor) {
		if (root != null) {
			root.accept(visitor);
		}
	}
	
	public void setRoot(Componentt component) {
		this.root = component;
	}
}


/**
 * 这个类是用来测试的
 * bylijinnan
 */
public class VisitorPattern {

	public static void main(String[] args) {
		//测试基本的访问者模式
		ObjectStructure objectStructure = new ObjectStructure();
		Element elememtA = new ConcreteElementA();
		Element elememtB = new ConcreteElementB();
		objectStructure.addElement(elememtA);
		objectStructure.addElement(elememtB);
		
		IVisitor visitor = new ConcreteVisitor1();
		objectStructure.handleRequest(visitor);
		
		visitor = new ConcreteVisitor2();
		objectStructure.handleRequest(visitor);
		
		//扩展:测试组合模式和访问者模式访问节点元素和叶子元素
		System.out.println();
		
		Compositee root = new Compositee("服装");
		Compositee c1 = new Compositee("男装");
		Compositee c2 = new Compositee("女装");
		Leaff leaf11 = new Leaff("夹克");
		Leaff leaf12 = new Leaff("男衬衣");
		Leaff leaf21 = new Leaff("裙子");
		Leaff leaf22 = new Leaff("女衬衣");
		
		root.addChild(c1);
		root.addChild(c2);
		c1.addChild(leaf11);
		c1.addChild(leaf12);
		c2.addChild(leaf21);
		c2.addChild(leaf22);
		
		ObjectStructuree objectStructure2 = new ObjectStructuree();
		objectStructure2.setRoot(root);
		IVisitorr visitor2 = new PrintNameDetailVisitor();
		objectStructure2.handleRequest(visitor2);
	}

}
0
5
分享到:
评论

相关推荐

    c++设计模式-行为型模式-访问者模式

    c++设计模式-行为型模式-访问者模式;qt工程;c++简单源码; 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新...

    研磨设计模式-part2

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

    研磨设计模式-part4

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

    研磨设计模式-part3

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

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

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

    设计模式-访问者(Visitor)模式详解和应用.pdf

    设计模式 -访问者(Visitor)模式详解和应用.pdf

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

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

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

    Visitor(访问者模式)属于行为型模式。意图:表示一个作用于某对象结构中的各元素的操作。

    C#设计模式-吕震宇

    设计模式(20)-Visitor Pattern 设计模式(19)-Observer Pattern 设计模式(18)-Command Pattern 设计模式(17)-Chain of Responsibility Pattern 设计模式(16)-Bridge Pattern 设计模式(15)-Facade ...

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

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

    online-books#dt-fe-weekly#189.精读《设计模式 - Visitor 访问者模式》1

    可以看到,要实现操作权转让到 Visitor,核心是元素必须实现一个 Accept 函数,将这个对象抛给 Visitor:从上面代码可以看出这样一条链路:Ele

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

    访问者模式(Visitor) 用意:适用于数据结构相对未定的系统,把数据结构和作用于结构上的操作间的耦合解开。

    设计模式--C++

    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#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式

    C#面向对象设计模式纵横谈(24):(行为型模式) Visitor 访问者模式

    研磨设计模式.part3(共4个)

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

    研磨设计模式.part2(共4个)

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

    研磨设计模式.part4(共4个)

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

    研磨设计模式.part1(共4个)

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

    (行为型模式) Visitor 访问者模式

    C#面向对象设计模式 (行为型模式) Visitor 访问者模式 视频讲座下载

Global site tag (gtag.js) - Google Analytics