设计模式(二十二):访问者模式

99 阅读1分钟

介绍

访问者模式(Visitor Pattern)属于行为型模式。我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。访问者对象就可以处理元素对象上的操作。

优点

  • 主要将数据结构与数据操作分离,解耦
  • 符合单一职责原则

缺点

  • 违反了依赖倒置原则,依赖了具体类,没有依赖抽象
  • 具体元素变更比较困难

应用

对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

实现

关键代码:在数据基础类里面有一个方法接受访问者,将自身引用传入访问者

interface ComputerPart {
    public void accept(ComputerPartVisitor computerPartVisitor);
 }

 class Monitor  implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
       computerPartVisitor.visit(this);
    }
 }

 class Mouse  implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
       computerPartVisitor.visit(this);
    }
 }

 class Keyboard  implements ComputerPart {
    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
       computerPartVisitor.visit(this);
    }
 }

 class Computer implements ComputerPart {
   
    ComputerPart[] parts;
  
    public Computer(){
       parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};      
    }

    @Override
    public void accept(ComputerPartVisitor computerPartVisitor) {
       for (int i = 0; i < parts.length; i++) {
          parts[i].accept(computerPartVisitor);
       }
       computerPartVisitor.visit(this);
    }
 }

 interface ComputerPartVisitor {
    public void visit(Computer computer);
    public void visit(Mouse mouse);
    public void visit(Keyboard keyboard);
    public void visit(Monitor monitor);
 }

 class ComputerPartDisplayVisitor implements ComputerPartVisitor {
 
    @Override
    public void visit(Computer computer) {
       System.out.println("Displaying Computer.");
    }
  
    @Override
    public void visit(Mouse mouse) {
       System.out.println("Displaying Mouse.");
    }
  
    @Override
    public void visit(Keyboard keyboard) {
       System.out.println("Displaying Keyboard.");
    }
  
    @Override
    public void visit(Monitor monitor) {
       System.out.println("Displaying Monitor.");
    }
 }

 class VisitorPatternDemo {
    public static void main(String[] args) {

       ComputerPart computer = new Computer();
       computer.accept(new ComputerPartDisplayVisitor());
    }
 }
Displaying Mouse.
Displaying Keyboard.
Displaying Monitor. 
Displaying Computer.