访问者模式(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 {
@Override
public String create(Paper element) {
// 艺术公司利用Paper元素操作
return "打印广告";
}
@Override
public String create(Cuprum element) {
// 艺术公司利用Cuprum元素制造铜像
return "孔子铜像";
}
}
public class MintCompany implements Company {
@Override
public String create(Paper element) {
// 造币公司利用Paper元素造纸币
return "纸币";
}
@Override
public 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 {
@Override
public String accept(Company visitor) {
// 让指定访问者visitor访问当前Paper元素
return visitor.create(this);
}
}
public class Cuprum implements Material {
@Override
public String accept(Company visitor) {
// 让指定访问者visitor访问当前Cuprum元素
return visitor.create(this);
}
}
# MaterialSet 对象结构(ObjectStructure)角色
public class MaterialSet {
/**
* 存储材料元素的集合
*/
private List<Material> list = new ArrayList<>();
/**
* 让指定访问者访问list集合中的所有元素
*
* @param visitor 指定的访问者
* @return 批量访问的结果
*/
public String accept(Company visitor) {
// 获取集合的迭代器
Iterator<Material> 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));
}
}