访问者模式

在类的内部结构不变的情况下,不同的访问者访问这个对象,都会呈现出不同的效果。

访问者模式有以下角色

  • 元素类:是一个抽象类或者接口,里面会定义一个接收(accept)访问者的抽象方法,使得每一个元素能被访问者访问。
  • 具体元素:继承或实现元素类,实现接收方法。
  • 访问者:一般是一个抽象类,里面涵括了可以访问每个具体元素的方法,使得访问者可以访问每个具体元素(一般有几个具体元素就会有几个这个样的方法,这些方法的方法名相同参数不同,参数都是具体元素,所以一般来说具体元素的种类应该是比较固定的)。
  • 具体访问者:访问者的具体实现

例如我们定义景区是一个元素类,西湖、长城是一个具体的元素类,游客就是访问者的抽象,那么游客A、游客B就是具体的访问者。

景区类中有一个接收方法参数是游客类型,由于多态特性所以我们可以传入游客A、游客B等子类。

游客类中会有多个访问方法,它们的方法名相同,参数不同,分别为西湖、长城等具体元素类

具体景区-西湖会实现父类中的接收抽象方法,然后方法中调用传入的游客对象的访问方法,参数设为this也就是西湖类的对象,这就相当于调用了游客类中的参数为西湖的访问方法。

具体类图如下

访问者模式_第1张图片

下面使用一个类似的样例,国家领导人进行国际访问来进行代码实现

元素类 - 国家

public abstract class Country {
    private String capital;

    public Country(String capital) {
        this.capital = capital;
    }

    public String getCapital() {
        return capital;
    }

    abstract void accept(NationalLeader leader);
}

具体元素类 - 美国、日本

public class America extends Country {

    public America(String capital) {
        super(capital);
    }

    @Override
    public void accept(NationalLeader leader) {
        leader.visit(this);
    }

}
public class Japan extends Country {

    public Japan(String capital) {
        super(capital);
    }

    @Override
    public void accept(NationalLeader leader) {
        leader.visit(this);
    }
}

访问者 - 国家领导人

public interface NationalLeader {
    void visit(America america);
    void visit(Japan japan);
    //这里面还可以访问 中国、巴西、法国、英国.....被访问的通常是固定不变的,而访问者可以是任何人,相对来说更加灵活
}

具体访问者 - 普京

public class Putin implements NationalLeader{
    @Override
    public void visit(America america) {
        System.out.println("普京抵达美国首都"+america.getCapital());
    }

    @Override
    public void visit(Japan japan) {
        System.out.println("普京抵达日本首都"+japan.getCapital());
    }
}

测试

public class VisitorTest {
    @Test
    public void test(){
        Country america = new America("华盛顿");
        america.accept(new Putin());
        Country japan = new Japan("东京");
        japan.accept(new Putin());
    }
}

=====结果=====
普京抵达美国首都华盛顿
普京抵达日本首都东京

优点:

  1. 使得数据结构(元素类)和作用于结构上的操作(访问者)解耦,使得操作集合可以独立变化。
  2. 便于灵活添加操作(访问者)。
  3. 将对各个元素的一组操作集中在一个访问者类当中。
  4. 可以跨越类层次结构,访问不同层次的元素类,做出相应的操作。

缺点:

  1. 增加新的元素会非常困难。
  2. 实现起来比较复杂,会增加系统的复杂性。
  3. 破坏封装,如果将访问行为放在各个元素中,则可以不暴露元素的内部结构和状态,但使用访问者模式的时候,为了让访问者能获取到所关心的信息,元素类不得不暴露出一些内部的状态和结构,就像收入和支出类必须提供访问金额和单子的项目的方法一样。

适用性:

  1. 数据结构稳定,作用于数据结构的操作经常变化的时候。
  2. 当一个数据结构中,一些元素类需要负责与其不相关的操作的时候,为了将这些操作分离出去,以减少这些元素类的职责时,可以使用访问者模式。
  3. 有时在对数据结构上的元素进行操作的时候,需要区分具体的类型,这时使用访问者模式可以针对不同的类型,在访问者类中定义不同的操作,从而去除掉类型判断。

你可能感兴趣的:(访问者模式)