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

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



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);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值