声明:
本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客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);
}
}