在类的内部结构不变的状况下,不同的访问者拜访这个对象,都会呈现出不同的成果。
访问者模式有以下角色
- 元素类:是一个抽象类或者接口,外面会定义一个接管 (accept) 访问者的形象办法, 使得每一个元素能被访问者拜访。
- 具体元素:继承或实现元素类,实现接管办法。
- 访问者:个别是一个抽象类,外面涵括了能够拜访每个具体元素的办法,使得访问者能够拜访每个具体元素(个别有几个具体元素就会有几个这个样的办法,这些办法的办法名雷同参数不同,参数都是具体元素,所以一般来说具体元素的品种应该是比拟固定的)。
- 具体访问者:访问者的具体实现
例如咱们定义景区是一个元素类,西湖、长城是一个具体的元素类,游客就是访问者的形象,那么游客 A、游客 B 就是具体的访问者。
景区类中有一个接管办法参数是游客类型,因为多态个性所以咱们能够传入游客 A、游客 B 等子类。
游客类中会有多个拜访办法,它们的办法名雷同,参数不同,别离为西湖、长城等具体元素类
具体景区 - 西湖会实现父类中的接管形象办法,而后办法中调用传入的游客对象的拜访办法,参数设为 this
也就是西湖类的对象,这就相当于调用了游客类中的参数为西湖的拜访办法。
具体类图如下
上面应用一个相似的样例,国家领导人进行国内拜访来进行代码实现
元素类 – 国家
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());
}
}
===== 后果 =====
普京到达美国首都华盛顿
普京到达日本首都东京
长处:
- 使得数据结构 (元素类) 和作用于构造上的操作 (访问者) 解耦,使得操作汇合能够独立变动。
- 便于灵便增加操作(访问者)。
- 将对各个元素的一组操作集中在一个访问者类当中。
- 能够逾越类层次结构,拜访不同档次的元素类,做出相应的操作。
毛病:
- 减少新的元素会十分艰难。
- 实现起来比较复杂,会减少零碎的复杂性。
- 毁坏封装,如果将拜访行为放在各个元素中,则能够不裸露元素的内部结构和状态,但应用访问者模式的时候,为了让访问者能获取到所关怀的信息,元素类不得不暴露出一些外部的状态和构造,就像支出和收入类必须提供拜访金额和单子的我的项目的办法一样。
适用性:
- 数据结构稳固,作用于数据结构的操作常常变动的时候。
- 当一个数据结构中,一些元素类须要负责与其不相干的操作的时候,为了将这些操作拆散进来,以缩小这些元素类的职责时,能够应用访问者模式。
- 有时在对数据结构上的元素进行操作的时候,须要辨别具体的类型,这时应用访问者模式能够针对不同的类型,在访问者类中定义不同的操作,从而去除掉类型判断。