设计模式---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
 25- public 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
 3- public interface ComputerVisitor { 
 public void accept(ComputerPartVisitor computerPartVisitor);
 }
- 对象继承”眼“,实现方法 - 1 
 2
 3
 4
 5
 6
 7
 8
 9- public 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
 55- public 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
 17- public 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 | 
