当前位置:首页 > 开发 > 编程语言 > 设计模式 > 正文

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

发表于: 2012-10-06   作者:bylijinnan   来源:转载   浏览:
摘要: 声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/ import java.util.ArrayList; import java.util.List; interface IVisitor { //第二次分派,Visitor调用Element void visitConcret
声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客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);
	}

}

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

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案
http://www.ibm.com/developerworks/cn/java/l-dpstruct/part1/ 把对象本身和对象的操作分离开 2、
访问者模式可在不修改已有程序结构前提下,定义该类层次结构的操作,通过添加额外的访问者来完成对
问题 在面向对象系统的开发和设计过程中,经常会遇到一种情况就是需求变更,经常我们做好的一个设计
定 义:表示作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这
设计模式(17):访问者模式(Visitor) 访问者模式(Visitor) 定义 表示一个作用于某对象结构中的各元素
  前言:【模式总览】——————————by xingoo   模式意图   对于某个对象或者一组对象
  前言:【模式总览】——————————by xingoo   模式意图   对于某个对象或者一组对象
访问者模式是对象的行为模式。访问者模式的目的是封装施加在某种数据结构元素上的操作。一旦一些操
23. Visitor 访问模式 2008-09-26 动机 (Motivation) 在软件构建过程中,由于需求的改变,某些层次
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号