为什么[GoF]在定义访问者模式时,要强调对象结构呢?其定义为:“表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。”
作为一个设计方案或设计结构,访问者模式这种结构可以用于两种场景:①解决表达式问题;②处理整体和部分结构的操作。
在场景①中,访问者表示的,是类层次如Person的一个操作,Visitor的新子类可以在不改变Person类层次的前提下,(模拟地)为Person定义新操作。
此时对象结构不是必需的,即使在通常情况下,Person的各种子类对象不单独存在而是构成数组或其他数据结构,例如,Group有一个最常见的ArrayList<Person>,保存各种具体元素(Person的各种子类)。也可以使用组合模式——例如将Group设计为Person的子类。但是所有这些数据结构并非访问者模式的本质特性,对象结构是一种附加的应用。例子
场景②,处理整体和部分结构的操作,是[GoF]对访问者模式的定义。在一些例子中,如https://en.wikipedia.org/wiki/Visitor_pattern的例子,它将汽车/Car以及汽车的部分如轮胎/Wheel、引擎/Engine、车体/Body作为汽车元素/ICarElement的子类型。在这种整体和部分关系场合,对象结构指Car这个整体。通过组合模式,将ICarElement的部件子类型构造成一个对象结构即Car。
所以,访问者模式是解决表达式问题的一种方案,可用于处理整体和部分结构的场合。
表达式问题/扩展性问题:
Person有子类Boy、Girl……等等;Person定义了方法say()、eat(int i)、walk()等。Person定义的接口,由其子类实现。
下面的表中,以Person的子类型为行,Person的方法为列。
| Person.say() | Person.eat() | Person.walk() | 新方法 |
Boy | @Override |
| ||
Girl |
| |||
新类型 |
|
|
|
|
相关术语:
expression problem (or extensibility problem)
virtual types or multi-methods
mixin