文章首发:
行为型模式:访问者模式java
十一大行为型模式之十一:访问者模式。设计模式
姓名 :访问者模式
英文名 :Visitor Pattern
价值观 :来访者即是客,招待就是
我的介绍 :
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
封装一些做用于某种数据结构中的各元素的操做,它能够在不改变数据结构的前提下定义做用于这些元素的新的操做。
(来自《设计模式之禅》)微信
先声明一下,下面故事全瞎编的。。。数据结构
咱们是否还记得 N 年前反腐开始的时候,有一段时间提倡官员宴请吃饭只能几菜几汤,不能超出。我记得那会刚读大一,军事理论的老师说到这个问题,也发表了他的一些想法,他以为这么作比较刻板。今天的故事就和宴请有关。如今中国企业发展愈来愈大,在社会中担任的责任也愈来愈大,政府也愈来愈重视企业,官员去参观企业是常有的事,而企业宴请官员也变得格外的常见。架构
故事的背景就是企业宴请各级官员。不一样级别的官员宴请的菜式就不同,每家企业的菜式丰富程度也不同。咱们这里的访问对象就用 Alibaba 和 Tencent 这 2 家公司,而访问者就用郭嘉领导人和省领导人作举例。这 2 家公司都跟喜来登酒店合做,Alibaba 合做方案是:宴请省级领导人及如下官员则十菜一汤,宴请郭嘉领导人及以上官员则十四菜两汤;Tencent 合做方案是:宴请省领导人及如下官员则八菜一汤,宴请郭嘉领导人及以上官员则十六菜两汤。机器学习
下面看看如何用访问者模式来实现上面的故事。ide
首先定义一个抽象类:企业。企业有一个共有的特性就是接受上级领导的访问。学习
/** * 企业 */ abstract class Company { public abstract void accept(Vistor vistor); }
上面故事咱们举例了 2 家企业,分别是 Alibaba 和 Tencent,这里实现这 2 家公司的宴请方案,并实现接待访问者方法。测试
Alibaba 宴请郭嘉领导人及以上官员是十四菜两汤,宴请省领导及如下是十菜一汤。this
/** * Alibaba 企业 */ class AlibabaCompany extends Company { @Override public void accept(Vistor vistor) { vistor.visit(this); } public String entertainBelowProvincialLeader(String leader) { return "Alibaba 接待" + leader + ":十菜一汤"; } public String entertainAboveNationalLeader(String leader) { return "Alibaba 接待" + leader + ":十四菜两汤"; } }
Tencent 宴请郭嘉领导人及以上是十六菜两汤,宴请省领导及如下是八菜一汤。
/** * Tencent 企业 */ class TencentCompany extends Company { @Override public void accept(Vistor vistor) { vistor.visit(this); } public String entertainBelowProvincialLeader(String leader) { return "Tencent 接待" + leader + ":八菜一汤"; } public String entertainAboveNationalLeader(String leader) { return "Tencent 接待" + leader + ":十六菜两汤"; } }
这里定义访问者接口,访问者接口有 2 个方法,分别是访问 Alibaba 企业和访问 Tencent 企业。
/** * 访问者接口 */ interface Vistor { void visit(AlibabaCompany alibabaCompany); void visit(TencentCompany tencentCompany); }
上面故事中有 2 个访问者,一个是郭嘉领导人,另外一个是省领导人,由于不一样企业对应不一样访问者有不一样的宴请方案,因此这里访问企业是须要调用对应企业的宴请方式。
省领导人访问企业时,须要调用企业对省领导及如下官员的宴请方案,为entertainBelowProvincialLeader()
/** * 省领导访问 */ class ProvincialLeaderVistor implements Vistor { @Override public void visit(AlibabaCompany alibabaCompany) { System.out.println(alibabaCompany.entertainBelowProvincialLeader("省领导")); } @Override public void visit(TencentCompany tencentCompany) { System.out.println(tencentCompany.entertainBelowProvincialLeader("省领导")); } }
郭嘉领导人访问企业时,须要调用企业对郭嘉领导人的宴请方案,为entertainAboveNationalLeader()
/** * 郭嘉领导访问 */ class NationalLeaderVistor implements Vistor { @Override public void visit(AlibabaCompany alibabaCompany) { System.out.println(alibabaCompany.entertainAboveNationalLeader("省领导")); } @Override public void visit(TencentCompany tencentCompany) { System.out.println(tencentCompany.entertainAboveNationalLeader("郭嘉领导")); } }
上面是访问者和被访问者的代码,由于企业是在喜来登酒店宴请领导人,因此这里还须要一个酒店,酒店里面有企业合做的名单,以及负责宴请各路领导的方法提供。
/** * 酒店 */ class Hotel { private List<Company> companies = new ArrayList<>(); public void entertain(Vistor vistor) { for (Company company : companies) { company.accept(vistor); } } public void add(Company company) { companies.add(company); } }
下面提供测试代码,看看运行的结果怎样。
public class VisitorTest { public static void main(String[] args) { AlibabaCompany alibabaCompany = new AlibabaCompany(); TencentCompany tencentCompany = new TencentCompany(); ProvincialLeaderVistor provincialLeaderVistor = new ProvincialLeaderVistor(); NationalLeaderVistor nationalLeaderVistor = new NationalLeaderVistor(); Hotel xilaideng = new Hotel(); xilaideng.add(alibabaCompany); xilaideng.add(tencentCompany); xilaideng.entertain(provincialLeaderVistor); xilaideng.entertain(nationalLeaderVistor); } } 打印结果: Alibaba 接待省领导:十菜一汤 Tencent 接待省领导:八菜一汤 Alibaba 接待郭嘉领导:十四菜两汤 Tencent 接待郭嘉领导:十六菜两汤
完整的访问者模式代码已经呈现,花 1 分钟思考一番,理解整个代码后咱们来看看下面的总结。
访问者模式有比较好的扩展性,看看访问者代码,咱们若是要新增一个访问者:市领导人,只需新增市领导人类,即可实现。固然也有它很差的地方,就是把被访问者暴露给访问者,使得访问者能够直接了解被访问者的全部东西。明白了优缺点,才能更好的在实际中运用,通常访问者模式运用于要求遍历多个不一样的对象的场景。
推荐阅读
设计模式系列文章持续更新中,欢迎关注公众号 LieBrother,一块儿交流学习。
公众号后台回复『大礼包』获取 Java、Python、IOS 等教程
加我的微信备注『教程』获取架构师、机器学习等教程