访问者模式(二十四)

Andy 2023年06月09日 600次浏览

我们使用了一个访问者类,它改变了元素类的执行算法
元素的执行算法可以随着访问者改变而改变
意图:主要将数据结构与数据操作分离。

菜鸟案例:
我们将创建一个定义接受操作的 ComputerPart 接口。Keyboard、Mouse、Monitor 和 Computer 是实现了 ComputerPart 接口的实体类。我们将定义另一个接口 ComputerPartVisitor,它定义了访问者类的操作。Computer 使用实体访问者来执行相应的动作。
VisitorPatternDemo,我们的演示类使用 Computer、ComputerPartVisitor 类来演示访问者模式的用法。
image.png

拆图
image.png
这里不是一个接口四个实现类这么简单,Computer 里面有一个ComputerPart 接口的数组,不用猜也知道是存它右边这三个实现类的,当然它有可能把自己也存进去了,可能性很高。
image.png
一个访问者的接口和访问者的实现了,连方法的参数都这么直白,就知道了,访问者可以访问Computer 所有的实现类
这直接说明,创建了一个ComputerPart的实体类Computer ,在构造方法里new出来了其他三个实体类加入到此对象的数组里,
创建了一个ComputerPartVisitor 的实体类ComputerPartDisplayVisitor当成参数传进Computer的 accept 方法,这有个误区,图上accept没有参数,但是实际中有参数
重点:传进去的参数对象会调用自身的visit() 访问此对象。
有点绕,就是ComputerPartVisitor.visit(this);,当然数组里的会遍历,到数组中的对象里的accept再调用ComputerPartVisitor.visit(this);
有点扯,但是它就是这么写的

上面的思路你可能有些混乱看下面的代码,建议从 (6) 顺着逻辑来,

直接看代码
(1)定义一个表示元素的接口
ComputerPart.java

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

(2)创建扩展了上述类的实体类。
Keyboard.java

public class Keyboard  implements ComputerPart {
 //调用传过来的对象的visit
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      computerPartVisitor.visit(this);
   }
}

Monitor.java

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

Mouse.java

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

Computer.java

public class Computer implements ComputerPart {
   
   ComputerPart[] parts;
 
   public Computer(){
   //在这构造方法里就new出来其他三个对象了并放进数组里
      parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()};      
   } 
 
 
   @Override
   public void accept(ComputerPartVisitor computerPartVisitor) {
      for (int i = 0; i < parts.length; i++) {
      //遍历,看有没有符合数组对象里的accept方法的,根据参数辨别
         parts[i].accept(computerPartVisitor);
      }
      //最后直接让传过来的参数对象调用visit,参数为当前对象
      computerPartVisitor.visit(this);
   }
}

(3)定义一个表示访问者的接口。
ComputerPartVisitor.java

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

(4)创建实现了上述类的实体访问者。
ComputerPartDisplayVisitor.java

public class ComputerPartDisplayVisitor implements ComputerPartVisitor {
 	//访问者重载的4个方法,这些是跟ComputerPart 的实体类相对应的
   @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.");
   }
}

(5)使用 ComputerPartDisplayVisitor 来显示 Computer 的组成部分。
VisitorPatternDemo.java

public class VisitorPatternDemo {
   public static void main(String[] args) {
 	//创建一个ComputerPart ,再往这个对象里的accept穿进去一个新的ComputerPartDisplayVisitor()
      ComputerPart computer = new Computer();
      computer.accept(new ComputerPartDisplayVisitor());
   }
}

执行程序,输出结果:

Displaying Mouse.
Displaying Keyboard.
Displaying Monitor.
Displaying Computer.

最后这些结果还是ComputerPartDisplayVisitor 访问者的数据,而ComputerPart 只提供了一个操作的接口,通过操作ComputerPart 某个实体类来输出ComputerPartDisplayVisitor 里相对应的数据
————————————————
版权声明:本文为CSDN博主「胖墩的IT」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43113679/article/details/99590257