您的位置:首页 > 其它

设计模式学习笔记(22)——访问者模式

2015-05-25 12:20 531 查看
一、模式定义

访问者模式即表示一个作用于某对象结构中的各元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

首先我们要明确一点就是访问者模式适用于数据结构相对稳定的系统。它是将数据的操作与数据结构进行分离了,如果某个系统的数据结构相对稳定,但是操作算法易于变化的话,就比较适用适用访问者模式,因为访问者模式使得算法操作的增加变得比较简单了。

二、模式结构



访问者模式主要包含如下几个角色:

Vistor: 抽象访问者。为该对象结构中的ConcreteElement的每一个类声明的一个操作。
ConcreteVisitor: 具体访问者。实现Visitor申明的每一个操作,每一个操作实现算法的一部分。
Element: 抽象元素。定义一个Accept操作,它以一个访问者为参数。
ConcreteElement: 具体元素 。实现Accept操作。
ObjectStructure: 对象结构。能够枚举它的元素,可以提供一个高层的接口来允许访问者访问它的元素。

三、模式实现

Visitor : 为该对象结构中 ConcreteElement 的每一个类声明一个 Visit 操作。

abstract class Visitor {
public abstract void VisitConcreteElementA(ConcreteElementA elementA);
public abstract void VisitConcreteElementB(ConcreteElementB elementB);
}

ConcreteVisitor : 实现每个由 Visitor 声明的操作。每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类。

class ConcreteVisitor1 extends Visitor {

@Override

public void VisitConcreteElementA(ConcreteElementA elementA) {

System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());

}

@Override

public void VisitConcreteElementB(ConcreteElementB elementB) {

System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());

}

}

class ConcreteVisitor2 extends Visitor {

@Override

public void VisitConcreteElementA(ConcreteElementA elementA) {

System.out.println(this.getClass().getName() + " 访问 " + elementA.getClass().getName());

}

@Override

public void VisitConcreteElementB(ConcreteElementB elementB) {

System.out.println(this.getClass().getName() + " 访问 " + elementB.getClass().getName());

}

}

Element : 定义一个Accpet操作,它以一个访问者为参数。

abstract class Element {
public abstract void Accept(Visitor visitor);
}

ConcreteElement : 实现 Element 声明的 Accept 操作。

class ConcreteElementA extends Element {

@Override

public void Accept(Visitor visitor) {

visitor.VisitConcreteElementA(this);

}

}

class ConcreteElementB extends Element {

@Override

public void Accept(Visitor visitor) {

visitor.VisitConcreteElementB(this);

}

}

ObjectStructure : 可以枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素。

class ObjectStructure {

private List<Element> elements = new ArrayList<Element>();

public void Attach(Element element) {

elements.add(element);

}

public void Detach(Element element) {

elements.remove(element);

}

public void Accept(Visitor visitor) {

for (Element elem : elements) {

elem.Accept(visitor);

}

}

}

测试代码

public class VisitorPattern {

public static void main(String[] args) {

ObjectStructure o = new ObjectStructure();

o.Attach(new ConcreteElementA());

o.Attach(new ConcreteElementB());

ConcreteVisitor1 v1 = new ConcreteVisitor1();

ConcreteVisitor2 v2 = new ConcreteVisitor2();

o.Accept(v1);

o.Accept(v2);

}

}

运行结果

ConcreteVisitor1 访问 ConcreteElementA
ConcreteVisitor1 访问 ConcreteElementB
ConcreteVisitor2 访问 ConcreteElementA
ConcreteVisitor2 访问 ConcreteElementB

[b]四、使用场景[/b]
1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。

2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: