访问者模式的基本思想:
软件系统中拥有一个由许多对象构成的、比较稳定的对象结构,这些对象的类都拥有一个 accept 方法用来接受访问者对象的访问。
访问者是一个接口,它拥有一个 visit 方法,这个方法对访问到的对象结构中不同类型的元素做出不同的处理。在对象结构的一次访问过程中,我们遍历整个对象结构,对每一个元素都实施 accept 方法,在每一个元素的 accept 方法中会调用访问者的 visit 方法,从而使访问者得以处理对象结构的每一个元素,我们可以针对对象结构设计不同的访问者类来完成不同的操作,达到区别对待的效果。
特征:
封装一些作用于某种数据结构中的单个元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。
访问者模式角色介绍:
Visitor:
接口或者抽象类,它定义了对每一个元素(Element)访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素个数是一样的,因此访问者模式要求元素的类族要稳定,如果经常添加、移除元素类,必然会导致频繁地修改 Visitor 接口,如果出现这种情况,则说明不适合使用访问者模式;
ConcreteVisitor:
具体地访问者,它需要给出对每一个元素类访问时所产生的具体行为;
Element:
元素接口或者抽象类,它定义了一个接受访问者(accept)的方法,其意义是指每一个元素都要可以被访问者访问;
ElementA,ElementB:
具体的元素类,它提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法;
ObjectStructure:
定义当中所提到的对象结构,对象结构是一个抽象表述,它内部管理了元素集合,并且可以迭代这些元素供访问者访问。
访问者模式的优点:
各角色职责分离,符合单一职责原则;
能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能,具有良好的扩展性;
使得数据结构和作用于结构上的操作解耦,使得操作集合可以独立变化;
灵活性。
访问者模式的缺点:
具体元素对访问者公布细节,违反了迪米特原则;
具体元素变更时导致修改成本大;
违反了依赖倒置原则,为了达到“区别对待”而依赖了具体类,没有依赖抽象。
访问者模式使用的场景:
对象结构比较稳定,但经常需要在此对象结构上定义新的操作;
需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免这些操作“污染”这些对象的类,也不希望在增加新操作时修改这些类。
访问者模式的应用:
重构
如果是一些经常需要变动逻辑的业务则非常适合使用访问者模式,如果是需要频繁增加新的业务的,则不适合,所以Android的UI展示部分其实理论上来说是适合使用访问者模式的,因为UI常常一个版本一个变化,如果当UI的变化不只是局限在XML中修修改改的话,而是已经体现在了代码中,那么可以考虑是否可以使用访问者模式进行修改。
目前实际项目中暂无这种情况,广告模块后续的UI渲染由于是根据不同的广告平台所下发的广告对象来进行对应的渲染,目前每个广告平台渲染视图的接口所需参数不太一样,但是可以考虑进行一下抽离封装,做成一个简单的Visitor试试看。
当你想要利用聚合的方式来使用多个已有类的功能时,也可以考虑使用访问者模式。