访问者模式(Visitor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。据《大话设计模式》中说算是最复杂也是最难以理解的一种模式了。
访问者模式 是一种将数据操作与数据结构分离的设计模式,它可以算是 23 中设计模式中最复杂的一个,但它的使用频率并不是很高,大多数情况下,你并不需要使用访问者模式,但是当你一旦需要使用它时,那你就是需要使用它了。
~
本篇文章内容包括:关于访问者模式、访问者模式 Demo
访问者模式(Visitor Pattern),是在 GoF 23 种设计模式中定义了的行为型模式。据《大话设计模式》中说算是最复杂也是最难以理解的一种模式了。
访问者模式 是一种将数据操作与数据结构分离的设计模式,它可以算是 23 中设计模式中最复杂的一个,但它的使用频率并不是很高,大多数情况下,你并不需要使用访问者模式,但是当你一旦需要使用它时,那你就是需要使用它了。
访问者模式 的基本想法是,软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个 accept 方法用来接受访问者对象的访问。访问者是一个接口,它拥有一个 visit 方法,这个方法对访问到的对象结构中不同类型的元素做出不同的处理。在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施 accept 方法,在每一个元素的 accept 方法中会调用访问者的 visit 方法,从而使访问者得以处理对象结构的每一个元素,我们可以针对对象结构设计不同的访问者类来完成不同的操作,达到区别对待的效果。
访问者模式 适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式
访问者模式主要包含以下 5 种角色:
# 访问者模式的优点
# 访问者模式的缺点
艺术公司利用“铜”可以设计出铜像,利用“纸”可以画出图画;造币公司利用“铜”可以印出铜币,利用“纸”可以印出纸币。对“铜”和“纸”这两种元素,两个公司的处理方法不同,所以该实例用访问者模式来实现比较适合。
# Company 抽象访问者(Visitor)角色
public interface Company {/*** 操作Page元素** @param element* @return*/String create(Paper element);/*** 操作Cuprum元素** @param element* @return*/String create(Cuprum element);
}
# ArtCompany/MintCompany 具体访问者(ConcreteVisitor)角色
public class ArtCompany implements Company {@Overridepublic String create(Paper element) {// 艺术公司利用Paper元素操作return "打印广告";}@Overridepublic String create(Cuprum element) {// 艺术公司利用Cuprum元素制造铜像return "孔子铜像";}
}public class MintCompany implements Company {@Overridepublic String create(Paper element) {// 造币公司利用Paper元素造纸币return "纸币";}@Overridepublic String create(Cuprum element) {// 造币公司利用Cuprum元素造铜币return "铜币";}
}
# Material 抽象元素(Element)角色
public interface Material {/*** 给指定访问者提供访问当前元素(就是this)的方法** @param visitor 指定的访问者* @return 访问当前元素返回的结果*/String accept(Company visitor);}
# Paper/Cuprum 具体元素(ConcreteElement)角色
public class Paper implements Material {@Overridepublic String accept(Company visitor) {// 让指定访问者visitor访问当前Paper元素return visitor.create(this);}
}
public class Cuprum implements Material {@Overridepublic String accept(Company visitor) {// 让指定访问者visitor访问当前Cuprum元素return visitor.create(this);}
}
# MaterialSet 对象结构(ObjectStructure)角色
public class MaterialSet {/*** 存储材料元素的集合*/private List list = new ArrayList<>();/*** 让指定访问者访问list集合中的所有元素** @param visitor 指定的访问者* @return 批量访问的结果*/public String accept(Company visitor) {// 获取集合的迭代器Iterator iterator = list.iterator();// 遍历集合,让集合中的所有材料元素都被当前访问者所访问String result = "";while (iterator.hasNext()) {result += iterator.next().accept(visitor) + " ";}// 返回某公司的作品集return result;}/*** 添加元素到材料集合中** @param element 待添加的元素*/public void add(Material element) {list.add(element);}/*** 删除集合中的指定元素** @param element 待删除的元素*/public void remove(Material element) {list.remove(element);}
}
public class Client {public static void main(String[] args) {// 创建材料元素集合MaterialSet ms = new MaterialSet();// 向集合中添加元素ms.add(new Paper());// 向集合中添加元素ms.add(new Cuprum());// 创建具体的访问者,让该访问者来访问对象结构中的所有元素Company artCompany = new ArtCompany();System.out.println(ms.accept(artCompany));System.out.println("==========================");// 创建具体的访问者,让该访问者来访问对象结构中的所有元素Company mintCompany = new MintCompany();System.out.println(ms.accept(mintCompany));}
}