1. 程式人生 > >訪問者模式(5.11)之物件結構

訪問者模式(5.11)之物件結構

為什麼[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

新型別

不修改原始碼的條件下,面向物件的語言如Java,更容易新增新的行,即擴充套件新型別;但是難以為Person新增新方法。而訪問者模式可以輔助Person新增新方法,但是難以擴充套件Person的新型別。

相關術語:

expression problem (or extensibility problem)

virtual types or multi-methods

 mixin