本文介绍了GoF中的访问者模式。
模式推演
应节涨价的商品
情人节来了,花鱼店的老板要对商品进行涨价,其中,鱼涨价两倍,花涨价三倍,但是过完节后,商品又必须回复原价,所以,老板不想修改商品本身的价格。
初始设计如下:
1 |
|
这种做法弊端很明显,当我需要修改涨价的倍数时,需要修改类本身,而且,情人节过后,也得修改类移除getValentineDayPrice接口。
封装变化
变化的部分是价格,我们希望可以修改价格,又不修改类本身,因此,我们将价格变化的部分用一个独立的类来负责,称为访问者:
1 | interface Visitor { |
这样做的好处是,不需要修改原先的类,即使引入新的商品,也只需要增加一个方法即可,当要回复原价的时候,也只需要修改访问者类即可。
接受访问
由于访问者需要获取Fish以及Flower的属性,所以我们设计一个被访问者接口,用于接收访问者:
1 | interface Visitable { |
调用
对于花鱼店的老板,也就是这个设计的用户而言,只需要调用访问者即可获取商品的价格。
1 | public class Main { |
结果:
1 | TotalCount:35 |
定义
访问者模式(Visitor Pattern):当想要为一个对象的组合添加新的能力,且封装并不重要时使用。
类图:
用途:
- 为对象的组合添加新的能力。
优点:
- 允许对组合结构加入新的操作,而无需改变结构本身;
- 想要加入新的操作,相对容易;
- 访问者所进行的操作,其代码是集中在一起的。
缺点:
- 当采用访问者模式时,就打破了组合类的封装;
- 因为游走的功能牵涉其中,所以对组合结构的改变就更加困难。