2008-09-04 62 views
3

作爲一個我自己的練習,我正在將一個示例程序翻譯成各種語言。在C#中開始,我有一個訪問者模式界面,如下所示:在動態語言中實現訪問者模式的首選方式?

interface Visitor 
    { 
     void Accept(Bedroom x); 
     void Accept(Bathroom x); 
     void Accept(Kitchen x); 
     void Accept(LivingRoom x); 
    } 

移動到紅寶石(或Python,或其他),我不再基於類型的編譯器得到調度。我應該在訪問者本身做派遣嗎?

class Cleaner 

    def accept(x) 
    acceptBedroom(x) if Bedroom === x 
    acceptBathroom(x) if Bathroom === x 
    acceptKitchen(x) if Kitchen===x 
    acceptLivingRoom(x) if LivingRoom===x 
    end 

    ... 

或者我應該做在房間的不同specializaions調度:

class Bathroom<Room 
    def initialize(name) 
    super(name) 
    end 
    def accept(visitor) 
    visitor.acceptBathroom(self) 
    end 
end 

還是有是在動態語言中使用的另一種優選的成語?

回答

3

我的建議是使用前一種方法。每種方法都有各自的優缺點。隨着房間類型的增長,前者難以維持;隨着清潔劑類型數量的增長,後者越來越困難。

在Ruby中,你可以嘗試

def accept(x) 
    send "accept#{x.class}".to_sym, x 
end 

PS:不是所有的動態類型語言是無法根據類型執行調度;一些可以推斷類型,或者失敗,可以使用強制轉換在重載選項中選擇適當的方法。

3

我會去第二個版本。第一個看起來像訪問者應該解決的那種代碼異味:long if-else-if或switch-case語句。