【行为型模式十九】访问者模式(Visitor)

原理图.png

访问者模式

1、什么是访问者模式

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

说明

表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。

2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。

3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。

4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。

5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;
可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。

访问者模式主要由三个角色组成

访问者
访问元素
元素集合(可以不是对象)
访问者就是对访问元素进行操作的访问对象。有可以对访问元素操作的方法。
访问元素即可以执行动作的对象。是可以被访问者修改的对象。
元素集合则顾名思义是访问元素的集合,将访问元素放到元素集合当中,等待访问。

以游戏而言,有许多种建筑物,居民楼、教堂、兵营等,这些都是访问元素,而访问者有清洁工、厨师等。整个游戏就是元素集合。
清洁工可以提升三者的清洁度,并且会提高居民楼的舒适度,教堂的信仰度,兵营的训练热情度等(想想看脏乱不堪的和干净整洁的区别);
厨师可以提升三者的幸福感(有好吃的总会让人感到幸福),并且会提高教堂的人气值,兵营的士气值;
这时候增加了一种访问者:客人
客人可以提升居民楼和教堂的人气值,教堂的传播度,兵营不允许访问。

这个时候通过有两种选择:

在居民楼、教堂、兵营等所有类中实现访问者能实现的事情,当增加访问者的时候则所有的访问元素类都需要进行修改
将访问者抽象出来,实现访问者模式,当增加访问者的时候,增加一个访问者类并实现对应方法即可

2、访问者模式用在什么地方

  • 一个对象结构(元素集合)包含很多类对象(不同的访问元素对象),它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。

  • 当你需要对一个对象结构中的对象进行很多不同的并且不相关的操作(可以直接在外界调用,属于可有可无的功能),并且不像因为这些操作而让对象变得过分拥挤。
    Visitor 使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用 Visitor 模式让每个应用仅包含需要用到的操作。

  • 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。

3、访问者模式的使用

  1. 定义访问元素,包括抽象对象与具体对象。

  2. 定义访问者,在抽象对象中访问者定义执行动作,访问元素中接收访问者的方法。
    访问元素增加 acceptVisitor(visitor) 方法(接收访问者),访问者增加 visitA(A)、visitB(B)、visitC(C) 方法(根据元素对象的多少)

  3. 通过访问元素调用访问者中的事件。在访问元素的 acceptVisitor 的实现方法中调用 [visitor visitX:self] 执行方法。

4、总结

访问者模式属于方法的扩展。优点如下:
在不同的对象中,如果存在大量重复的代码,可以把代码封装到访问者中。降低代码的冗余度。
易于增加访问者,通过访问者实现不同的方法。在不更改访问元素结构的前提下增加实现的方法。
不过同时也有一个很严重的缺点:
如果增加了一种访问元素,那么所有的访问者都需要增加对应的方法,导致增加访问元素的成本增加。
所以,最好在能确定具体元素数量的时候再使用访问者模式。

细节.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值