访问者模式(Visitor Pattern)定义 伪动态双亲委派
- 表示一个作用于某对象结构中的各种元素的操作. 它使你可以在不改变各元素的前提下定义作用于这些元素的操作
解析UML
- Visitor接口: 它定义了对每一个元素(Elemnent)的访问行为, 它的方法个数理论上来讲与元素的个数是一致的(Elemnent的实现类的个数)
- ConcreteVisitor: 具体的访问者, 它要对每一个元素访问时产生具体的行为
- Elemnent接口: 元素接口, 定义一个接受访问者(accept)的方法
- ConcreteElement : 具体的元素类, 它提供接受访问者的具体实现
- ObjectStructure: 访问者模式中的对象结构, 具体就是,具有容器性质或者符合对象特性的类, 再就是它必须含有一组元素, 并且可以迭代这些元素, 提供给访问者访问它的元素
总结: 这个模式就是为了让访问者可以方便的访问对象结构而存在
访问者模式的特点:
- 访问者模式将数据结构和作用于结构上的操作解耦合, 使得操作集合可相对自由的演化
- 访问者模式适用于数据结构相对稳定算法又易变化的系统. 应为访问者模式是的算法操作增加而变得容易. 若系统数据结构对象易于变化, 经常有新的数据对象增加进来, 则不适合使用访问者模式
- 访问者模式的优点是增加操作容易, 因为增加操作意味着增加新的访问者. 访问者模式将有关行为集中到一个访问者对象中, 其改变不影响系统数据结构, 其缺点是增加新的数据结构很困难
访问者模式的优缺点以及适用性
- 优点:
- 使得数据结构和作用于结构上的操作解耦, 是的操作集合可以独立变化
- 添加新的操作或者说访问者会非常的容易
- 将各个元素的一组操作集中在一个访问者类中
- 使得类层次结构不改变的情况下, 可以针对各个层次做出不同的操作, 而不影响类层次结构的完整性
- 可以跨越类层次结构, 访问不同层次的元素类, 做出相应的操作
- 缺点:
- 增加新的元素非常的困难
- 实现起来比较复杂
- 破坏封装, 如果将访问行为放在各个元素中门, 则可以不暴露元素的内出就够和状态, 但使用访问者模式的时候, 为了让访问者能获得新的信息, 元素类不得不暴露一些内部的状态和结构
- 适用性:
- 数据结构稳定, 作用于数据结构操作经常变化的时候
- 当一个数据结构中, 一些元素类需要负责与其不相关的操作的时候, 为了将这些操作分离出去, 以减少这些元素类的职责时. 可以使用该模式
- 有时在对数据结构上的原型进行操作的时候, 需要区分具体的类型, 这时使用访问者模式可以针对不同的类型, 在访问者类中定义不同的操作, 从而去除类型判断.
高级讲解
- 静态分派以及多分派:
- 按照变量的静态类型进行分派, 从而确定方法的执行版本, 静态分派在编译时期就可以确定方法的版本. 静态分批最典型的就是方法的重载
- 在静态分派的判断的时候, 根据多个判断依据判断出方法的依据, 这就是多分派的概念
- 动态分派与单分派:
- 与 静态分派相反, 典型的就是多态
- 在动态分派的判断下, 获取到多态下 实际引用类型, 判断依据是实际引用类型只有一个判断依据, 这就是单分派的概念
- 动态分派伪双分派:
- accept调用访问者, 根据元素的实际类型, 调用实际的accept
- accept版本确定的情况下, 其中的访问者的类型再次确认, 实现动态双分派的过程
- 这里的双分, 实际上是不同多态的单次判断: 我的理解
访问者模式多层次操作
- 看UML, 简单明了
- 可以加抽象, 继承, 形成多个层次的继承实现继承体系
- 调用接口规范的方法的时候, 各个层次操作不会改变层次原本结构, 操作随你定