设计模式---05.访问者模式
访问者模式
访问者模式是一种对象和对象的访问者分开的一种设计模式,在一个对象稳定的情况下,使用访问者模式可以更好的扩展对数据的访问。 相当于是我们在对象里面安插了一个“眼”,这个眼能够被外面实现,然后能拿到当前对象的各个属性。
举个例子
组装一台电脑,对于组装的对于组装者来说,只关心一个电脑零件构成(CPU,内存,鼠标键盘)。而对于电脑的消费者,关心的是电脑各个零件的价格以及总价。 而对于有些人来说对于,可能只关心电脑各个零件的重要性以及核心程度。综上所述我们操作的对象是一个电脑,对象是不变的,电脑的访问者来说是不同的,他们从不同的维度来分析这个电脑的属性。下面我们就用类图来表示访问者模式的大概结构:
对于访问者模式来说有以下几个实现步骤:
定义一个对象(可以是一个基类,也可是其他)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25public class ComputerPartBase {
private final String partName;
private final int coreLevel;
private final double price;
public ComputerPartBase(String partName, int coreLevel, double price) {
this.partName = partName;
this.coreLevel = coreLevel;
this.price = price;
}
public String getPartName() {
return partName;
}
public int getCoreLevel() {
return coreLevel;
}
public double getPrice() {
return price;
}
}定义一个接口,实现”插眼”的约束
1
2
3public interface ComputerVisitor {
public void accept(ComputerPartVisitor computerPartVisitor);
}对象继承”眼“,实现方法
1
2
3
4
5
6
7
8
9public class ComputerPartBase implements ComputerVisitor {
//.....
public void accept(ComputerPartVisitor computerPartVisitor) {
}
}各个零件的实现
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
55public class CPU extends ComputerPartBase {
public CPU() {
super("CPU", 10,2000.00d);
}
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Keyboard extends ComputerPartBase implements ComputerVisitor {
public Keyboard() {
super("keyboard", 1, 10);
}
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Memery extends ComputerPartBase implements ComputerVisitor {
public Memery() {
super("memery", 8, 200d);
}
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Monitor extends ComputerPartBase implements ComputerVisitor {
public Monitor() {
super("monitor", 2, 800);
}
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}
public class Mouse extends ComputerPartBase implements ComputerVisitor {
public Mouse() {
super("mouse", 2, 100);
}
public void accept(ComputerPartVisitor computerPartVisitor) {
computerPartVisitor.visit(this);
}
}真正的”眼“的接口
1
2
3
4
5
6
7
8
9
public interface ComputerPartVisitor {
public void visit(CPU cpu);
public void visit(Memery memery);
public void visit(Mouse mouse);
public void visit(Keyboard keyboard);
public void visit(Monitor monitor);
}访问者通过实现
眼
来获取数据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//电脑的组成
public class ComputerPartStrutchNameVisitor implements ComputerPartVisitor {
private List<String> partSet=new ArrayList<>();
public void visit(CPU cpu) {
partSet.add(cpu.getPartName());
}
public void visit(Memery memery) {
partSet.add(memery.getPartName());
}
public void visit(Mouse mouse) {
partSet.add(mouse.getPartName());
}
public void visit(Keyboard keyboard) {
partSet.add(keyboard.getPartName());
}
public void visit(Monitor monitor) {
partSet.add(monitor.getPartName());
}
public String getNeedPart(){
return partSet.stream().collect(Collectors.joining(","));
}
}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
//电脑的组装价格
public class ComputerPartPriceVisitor implements ComputerPartVisitor {
private double price = 0d;
public void visit(CPU cpu) {
price += cpu.getPrice();
}
public void visit(Memery memery) {
price += memery.getPrice();
}
public void visit(Mouse mouse) {
price += mouse.getPrice();
}
public void visit(Keyboard keyboard) {
price += keyboard.getPrice();
}
public void visit(Monitor monitor) {
price += monitor.getPrice();
}
public double getPrice(){
return price;
}
}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//获得电脑的核心等级
public class ComputerPartCoreLevelVisitor implements ComputerPartVisitor {
private List<String> levelList = new ArrayList<>();
public void visit(CPU cpu) {
levelList.add("CPU:"+cpu.getCoreLevel());
}
public void visit(Memery memery) {
levelList.add("Memery:"+memery.getCoreLevel());
}
public void visit(Mouse mouse) {
levelList.add("Mouse:"+mouse.getCoreLevel());
}
public void visit(Keyboard keyboard) {
levelList.add("Keyboard:"+keyboard.getCoreLevel());
}
public void visit(Monitor monitor) {
levelList.add("Monitor:"+monitor.getCoreLevel());
}
public String getCoreLevel(){
return levelList.stream().collect(Collectors.joining(","));
}
}调用的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class AppMain {
public static void main(String[] args) {
Computer computer = new Computer();
ComputerPartStrutchNameVisitor computerPartVisitor = new ComputerPartStrutchNameVisitor();
computer.accept(computerPartVisitor);
System.out.println("组装一个电脑需要零件:" + computerPartVisitor.getNeedPart());
ComputerPartPriceVisitor computerPartPriceVisitor = new ComputerPartPriceVisitor();
computer.accept(computerPartPriceVisitor);
System.out.println("组装一个电脑需要Money:" + computerPartPriceVisitor.getPrice());
ComputerPartCoreLevelVisitor computerPartCoreLevelVisitor = new ComputerPartCoreLevelVisitor();
computer.accept(computerPartCoreLevelVisitor);
System.out.println("电脑硬件的核心优先级为:" + computerPartCoreLevelVisitor.getCoreLevel());
}
}
输出的结果为:
1 | 组装一个电脑需要零件:CPU,memery,monitor,keyboard,mouse |