2012-06-28 30 views
1

SimpleDelegator有什麼替代方案來利用多態而不修改底層對象。Polymorphic Ruby SimpleDelegator

這是一個例子和SimpleDelegator沒有解決的問題。

目標是能夠用其他任何(yak_food)包裝原始對象(delicious_food),以便替換方法(delicious?)取決於底層的未替換方法。

class Food 
    def initialize(color) 
    @color = color 
    end 

    def delicious? 
    color == :red 
    end 

    def color 
    @color 
    end 
end 

class FoodTasteOverride < SimpleDelegator 
    def color 
    :green 
    end 
end 

delicious_food = Food.new(:red) 
yak_food = FoodTasteOverride.new delicious_food 

delicious_food.delicious? # true - expected 
yak_food.delicious? # expecting false, but is true since the color come from delicious_food 

什麼是將實際使用替代方法的替代方案?限制是你不能修改底層對象,它的類或者克隆。

約束意味着你不能做到這一點:

yak_food = delicious_food.clone 
def yak_food.color 
    :green 
end 

回答

3

另一種方法是使用擴展擴展您的實例的方法。 (這是大多數DCI實現都在運行時延長使用行爲對象)

class Food 

    attr_reader :color 

    def initialize(color) 
    @color = color 
    end 

    def delicious? 
    self.color == :red 
    end 

end 

module FoodTasteOverride 
    def color 
    :green 
    end 
end 


normal_food = Food.new(:red) 
delicious_food = Food.new(:red) 
yak_food = normal_food.extend(FoodTasteOverride) 

puts delicious_food.delicious? # true - expected 
puts yak_food.delicious? #false because the color is now green. 
+0

使用模塊在這種情況下,似乎更合理的,我也是如此。裝飾者不應該改變內部。 –

+0

好主意。由於某種原因,沒有考慮「擴展」。 –