读《研磨设计模式》-代码笔记-访问者模式-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);
	}

}

你可能感兴趣的:(java,设计模式)