设计模式之访问者模式

访问者模式(Visitor Pattern),表示一个作用于某对象结构中的各元素的操作,可以在不改变各元素的类的前提下定义作用于这些元素的新操作,属于行为型模式。

组成

访问者模式由抽象访问者 Visitor、具体访问者 ConcreteVisitor 、抽象元素 Element 、具体元素 ConcreteElement 和对象结构 ObjectStructure 组成。

其中 Element 定义一个 accept 操作,以一个访问者为参数; ConcreteElement 为 Element 的具体实现,通过传入的访问者实现 accept 操作; ObjectStructure 能够枚举所包含的元素,并提供允许访问其元素的高层接口; Visitor 为 ObjectStructure 中元素的每一个类声明 visit 操作;ConcreteVisitor 实现 Visitor 中定义的操作,每个操作实现对应 ObjectStructure 中元素的一个类。

优点

将数据结构和作用于结构上的操作解耦,使增加和修改访问操作变得容易。

将一组元素类的访问行为集中到一个访问者对象中,而非分散到各个元素类中。

缺点

增加新的元素类很困难,每增加一个新的元素类,都需要在 Visitor 增加新的接口,并在每一个具体访问者类中增加相应的具体操作。

破坏元素的封装,需要暴露给访问者使用。

使用场景

一个对象结构中包含多个类型的对象,需要执行依赖其具体类型的操作,且数据结构相对稳定,而作用于结构上的操作需要频繁变动时,可以使用访问者模式。

设计原则

遵循倾斜的开闭原则(修改访问行为遵循开闭原则,增加新元素破坏开闭原则)。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public interface Element {
void accept(Visitor visitor);
}

public class ElementA implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visitElementA(this);
}
}

public class ElementB implements Element {
@Override
public void accept(Visitor visitor) {
visitor.visitElementB(this);
}
}

public interface Visitor {
void visitElementA(ElementA elementA);
void visitElementB(ElementB elementB);
}

public class ConcreteVisitor implements Visitor {

@Override
public void visitElementA(ElementA elementA) {
System.out.println(elementA.getClass().getSimpleName() + "被 visitElementA 访问");
}

@Override
public void visitElementB(ElementB elementB) {
System.out.println(elementB.getClass().getSimpleName() + "被 visitElementB 访问");
}
}

public class ObjectStructure {

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

public void attach(Element element) {
elements.add(element);
}

public void detach(Element element) {
elements.remove(element);
}

public void accept(Visitor visitor) {
elements.forEach(element -> element.accept(visitor));
}
}

public class Client {
public static void main(String[] args) {
ObjectStructure objectStructure = new ObjectStructure();

objectStructure.attach(new ElementA());
objectStructure.attach(new ElementB());

objectStructure.accept(new ConcreteVisitor());
}
}
打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • © 2016-2020 姜越

谢谢老板

支付宝
微信