📓 Archive

  • Pricing
  • Chess
  • Syntax
  • 23-VISITOR

    FGJ: Create:2024/03/28 Update: (2024-10-24)

    访问者模式 #

    • 描述 #

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

      访问模式可以有变形,比如有些写法中被访问的是抽象类,而另外的是接口实现。

      ASM里面就用到了访问者模式来处理字节码信息。

    • UML #

    • 代码实现 #

      public class Main {
          public static void main(String[] args) {
      
              List<Staff> staffs = new ArrayList<>();
              staffs.add(new Manager("经理-A"));
              staffs.add(new Manager("经理-B"));
              staffs.add(new Engineer("工程师-A"));
              staffs.add(new Engineer("工程师-B"));
              staffs.add(new Engineer("工程师-C"));
              staffs.add(new Engineer("工程师-D"));
      
              CEOVisitor ceoVisitor = new CEOVisitor();
              for (Staff staff : staffs) {
                  staff.accept(ceoVisitor);
              }
      
              System.out.println();
      
              CTOVisitor ctoVisitor = new CTOVisitor();
              for (Staff staff : staffs) {
                  staff.accept(ctoVisitor);
              }
          }
      }
      

      active(访问) #

      public interface Visitor {
          void visit(Engineer engineer);
          void visit(Manager manager);
      }
      
      public class CEOVisitor implements Visitor {
      
          @Override
          public void visit(Engineer engineer) {
              System.out.println("CEO -visit-> 工程师: " + engineer.name + ", KPI: " + engineer.kpi);
          }
      
          @Override
          public void visit(Manager manager) {
              System.out.println("CEO -visit-> 经理: " + manager.name + ", KPI: " + manager.kpi +
                      ", 新产品数量: " + manager.getProducts());
          }
      }
      
      public class CTOVisitor implements Visitor {
      
          @Override
          public void visit(Engineer engineer) {
              System.out.println("CTO -visit-> 工程师: " + engineer.name + ", 代码行数: " + engineer.getCodeLines());
          }
      
          @Override
          public void visit(Manager manager) {
              System.out.println("CTO -visit-> 经理: " + manager.name + ", 产品数量: " + manager.getProducts());
          }
      }
      

      passive(被访问) #

      public abstract class Staff {
      
          public String name;
          public int kpi;// 员工KPI
      
          public Staff(String name) {
              this.name = name;
              kpi = new Random().nextInt(10);
          }
          // 核心方法,接受Visitor的访问
          public abstract void accept(Visitor visitor);
      }
      
      public class Engineer extends Staff {
      
          public Engineer(String name) {
              super(name);
          }
      
          @Override
          public void accept(Visitor visitor) {
              visitor.visit(this);
          }
          // 工程师一年的代码数量
          public int getCodeLines() {
              return new Random().nextInt(10 * 10000);
          }
      }
      
      public class Manager extends Staff {
      
          public Manager(String name) {
              super(name);
          }
      
          @Override
          public void accept(Visitor visitor) {
              visitor.visit(this);
          }
      
          // 一年做的产品数量
          public int getProducts() {
              return new Random().nextInt(10);
          }
      }
      

    • Reference #


    comments powered by Disqus