十 行为型-访问者模式

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

image.png

定义

主要将数据结构与数据操作分离。

UML图

下面就以人类分为男人和女人这个例子来实现访问者模式。UML图如下:

image.png

1. Action

  抽象的状态类,主要声明以下两个方法。

  这里的关键在于人只分男人和女人,这个性别的分类是稳定的,所以可以在状态类中,增加“男人反应”和“女人反应”两个方法,方法个数是稳定的,不会容易发生变化。

public abstract class Action {

    //得到男人的结论或反应
    public abstract void getManConclusion(Man man);

    //得到女人的结论或反应
    public abstract void getWomanConclusion(Woman woman);

}
复制代码

2. Person

  人的抽象类。只有一个“接受”的抽象方法,它是用来获得“状态”对象的。

public abstract class Person {
  //接受
  public abstract void accept(Action action);
}
复制代码

3. Action类的具体实现类

  这里以成功类(Success)为例,失败类(Fail)同理。

public class Success extends Action {

   @Override
   public void getManConclusion(Man man) {
       System.out.println("男人成功...");
   }

   @Override
   public void getWomanConclusion(Woman woman) {
       System.out.println("女人成功...");
   }
}
复制代码

4. Person类的具体实现类

这里以男人类(Man)为例,女人类(Woman)同理。

这里用到了双分派,即首先在客户程序中将具体状态作为参数传递给Man类完成了一次分派,然后Man类调用作为参数的“具体方法”中的方法getManConclusion(),同时将自己(this)作为参数传递进去,这便完成了第二次分派。accept方法就是一个双分派操作,它得到执行的操作不仅决定于Action类的具体状态,还决定于它访问的Person的类别。

public class Man extends Person {

   @Override
   public void accept(Action action) {
       action.getManConclusion(this);
   }
}
复制代码

5. 结构对象

public class ObjectStructure {

   private List<Person> elements = new LinkedList<>();

   //增加
   public void attach(Person person) {
       elements.add(person);
   }

   //移除
   public void detach(Person person) {
       elements.remove(person);
   }

   //查看显示
   public void display(Action action) {
       for (Person person : elements) {
           person.accept(action);
       }
   }

}
复制代码

6. Client客户端

public class Client {

   public static void main(String[] args) {
       ObjectStructure objectStructure = new ObjectStructure();

       objectStructure.attach(new Man());
       objectStructure.attach(new Woman());

       //成功
       Success success = new Success();
       objectStructure.display(success);

       //失败
       Failing failing = new Failing();
       objectStructure.display(failing);
   }

}

复制代码

image.png

猜你喜欢

转载自juejin.im/post/7018719362131427341