1 Visitor Pattern 访问者模式
目的:使用一个访问者类,改变被访问元素类的执行算法;
实现:主要将数据结构与数据操作分离。
1.访问者模式包括两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,一个是元素层次结构,提供了抽象元素和具体元素。相同的访问者可以以不同的方式访问不同的元素,相同的元素可以接受不同访问者以不同访问方式访问;
2.增加新的访问者无须修改原有系统,系统具有较好的可扩展性;
3.需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作”污染”这些对象的类,使用访问者模式将这些封装到类中。
2 实现
代码场景:朝鲜战争中,中国志愿军和联合国军队朝鲜半岛的干预。
1. 南北朝鲜就是具体元素角色
2. 外部干预是具体访问者角色。
2.1 代码实现
抽象元素角色:Country类
public abstract class Country {
// 使民族统一
public abstract void uniteNation();
// 并肩作战
public abstract void fightWith(Visitor visitor);
}
具体元素角色:SouthKorea类
public class SouthKorea extends Country {
@Override
public void fightWith(Visitor visitor) {
visitor.intervene(this);
}
@Override
public void uniteNation() {
System.out.println("---------------------------大韩民国--------------------------");
System.out.println("大韩民国:宇宙是我们的思密达~");
}
}
具体元素角色:NorthKorea类
public class NorthKorea extends Country {
@Override
public void fightWith(Visitor visitor) {
visitor.intervene(this);
}
@Override
public void uniteNation() {
System.out.println("---------------------朝鲜民主主义人民共和国---------------------");
System.out.println("朝鲜民主主义人民共和国:为了民族统一,为了共产主义而战~");
}
}
抽象访问者角色:Visitor类
public abstract class Visitor {
public abstract void intervene(NorthKorea northKorea);
public abstract void intervene(SouthKorea southKorea);
}
具体访问者角色:UNMilitary类
public class UNMilitary extends Visitor {
@Override
public void intervene(NorthKorea northKorea) {
// 嘲讽技能
System.out.println("--------访问者---------美军第十军团仁川江登陆-->北朝鲜--------------");
System.out.println("联合国军嘲讽技能:圣诞节我们就回家了~");
}
@Override
public void intervene(SouthKorea southKorea) {
System.out.println("--------访问者---------美军第十军团仁川江登陆-->南朝鲜------------");
System.out.println("麦克阿瑟率领美军,在美英两国三百多艘军舰和五百多架飞机掩护下,成功登陆仁川~");
southKorea.uniteNation();
System.out.println("从朝鲜军队后方突袭,切断朝鲜半岛的蜂腰部一线,迅速夺回了仁川港和附近岛屿~");
}
}
具体访问者角色:ChineseCommunistForces类
public class ChineseCommunistForces extends Visitor {
@Override
public void intervene(NorthKorea northKorea) {
System.out.println("--------访问者---------中国人民志愿军跨过鸭绿江-->北朝鲜------------");
System.out.println("抗美援朝,保家卫国~");
northKorea.uniteNation();
System.out.println("发动五次战役,血战上甘岭~");
}
@Override
public void intervene(SouthKorea southKorea) {
// 嘲讽技能
System.out.println("--------访问者---------中国人民志愿军跨过鸭绿江-->南朝鲜------------");
System.out.println("志愿军嘲讽技能:你们是帝国主义走狗~");
}
}
元素集合角色:Korea类
public class Korea {
public static List<Country> getList() {
List<Country> korea = new ArrayList<Country>();
System.out.println("1948年5月10日 大韩民国成立");
korea.add(new SouthKorea());
System.out.println("1948年9月 朝鲜民主主义人民共和国成立");
korea.add(new NorthKorea());
System.out.println("在美、苏影响下 朝鲜半岛出现了南北阵营");
return korea;
}
}
2.2 涉及角色
在访问者模式结构图中包含如下几个角色:
Vistor(抽象访问者):抽象访问者为对象结构中每一个具体元素类 ConcreteElement 声明一个访问操作,从这个操作的名称或参数类型可以清楚知道需要访问的具体元素的类型,具体访问者需要实现这些操作方法,定义对这些元素的访问操作。
Vistor(抽象访问者):抽象访问者为对象结构中每一个具体元素类 ConcreteElement 声明一个访问操作,从这个操作的名称或参数类型可以清楚知道需要访问的具体元素的类型,具体访问者需要实现这些操作方法,定义对这些元素的访问操作。
ConcreteVisitor(具体访问者):具体访问者实现了每个由抽象访问者声明的操作,每一个操作用于访问对象结构中一种类型的元素。
Element(抽象元素):抽象元素一般是抽象类或者接口,它定义一个 accept() 方法,该方法通常以一个抽象访问者作为参数。【稍后将介绍为什么要这样设计。】
ConcreteElement(具体元素):具体元素实现了 accept() 方法,在 accept() 方法中调用访问者的访问方法以便完成对一个元素的操作。
ObjectStructure(对象结构):对象结构是一个元素的集合,它用于存放元素对象,并且提供了遍历其内部元素的方法。它可以结合组合模式来实现,也可以是一个简单的集合对象,如一个 List 对象或一个 Set 对象。
2.3 调用
调用者:
public class Client {
public static void main(String[] args) {
ChineseCommunistForces ccf = new ChineseCommunistForces();
UNMilitary unm = new UNMilitary();
List<Country> countryList = Korea.getList();
System.out.println("-------------------------朝鲜战争爆发-----------------------");
for (Country country : countryList) {
country.fightWith(unm);
country.fightWith(ccf);
}
}
}
结果:
1948年5月10日 大韩民国成立
1948年9月 朝鲜民主主义人民共和国成立
在美、苏影响下 朝鲜半岛出现了南北阵营
-------------------------朝鲜战争爆发-----------------------
--------访问者---------美军第十军团仁川江登陆-->南朝鲜------------
麦克阿瑟率领美军,在美英两国三百多艘军舰和五百多架飞机掩护下,成功登陆仁川~
---------------------------大韩民国--------------------------
大韩民国:宇宙是我们的思密达~
从朝鲜军队后方突袭,切断朝鲜半岛的蜂腰部一线,迅速夺回了仁川港和附近岛屿~
--------访问者---------中国人民志愿军跨过鸭绿江-->南朝鲜------------
志愿军嘲讽技能:你们是帝国主义走狗~
--------访问者---------美军第十军团仁川江登陆-->北朝鲜--------------
联合国军嘲讽技能:圣诞节我们就回家了~
--------访问者---------中国人民志愿军跨过鸭绿江-->北朝鲜------------
抗美援朝,保家卫国~
---------------------朝鲜民主主义人民共和国---------------------
朝鲜民主主义人民共和国:为了民族统一,为了共产主义而战~
发动五次战役,血战上甘岭~
参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.