2016-09-28 32 views
1

我正在學習Ruby的Design Pattern並遇到Observer方法。我試圖自定義我自己的觀察者方法來幫助我理解它,但它返回一個錯誤。這裏是我想出的:如何使用Ruby Observer方法同時更新兩個參數?

class YummyTastyDonut 
    def update(changed_order) 
     puts "Kitchen: Yo, change the order to #{changed_order.order}!" 
     puts "Front: Order for #{changed_order.name}!" 
     puts "Front: The price will now be #{changed_order.order_price} " 
    end 
end 


class Customer 
    attr_reader :name, :order 
    attr_accessor :order_price 

    def initialize(name, order, order_price) 
     @name = name 
     @order = order 
     @order_price = order_price 
     @observers = [] 
    end 

    def order=(new_order, new_price) 
     @order = new_order 
     @order_price = new_price 
     notify_observers 
    end 

    def notify_observers 
     @observers.each do |observer| 
      observer.update(self) 
     end 
    end 

    def add_observer(observer) 
     @observers << observer 
    end 

    def delete_observer(observer) 
     @observers.delete(observer) 
    end 
end 

如果你讀了這本書,我改了類名,但本質是一樣的。我改變的一件事是order=方法;它現在接受兩個參數而不是一個參數。

目標是在創建新的Customer後,我希望新客戶能夠更改我的訂單並通知YummyTastyDonut。但是,我希望能夠更新兩件東西:orderorder_price(顯然,如果我更改了訂單,價格也會發生變化)。我想YummyTastyDonut來回應我的變化。

igg = Customer.new("Iggy", "Bacon Donut", 10) 
=> #<Customer:0x0056212e48a940 @name="Iggy", @order="Bacon Donut", @order_price=10, @observers=[]> 

donut = YummyTastyDonut.new 
=> #<YummyTastyDonut:0x0056212e4894c8> 

## Updating my order and order_price ## 

    igg.order = ("yummy butter donut", 15) 
#(repl):1: syntax error, unexpected ',', expecting ')' 
#igg.order = ("yummy butter donut", 15) 

如果我使用此order=方法只接受一個參數,它的工作方式與預期的一樣。

def order=(new_order) 
    @order = new_order 
    notify_observers 
end 

igg.order = "Triple bacon donut explosion" 
Kitchen: Yo, change the order to Triple bacon donut explosion! 
Front: Order for Iggy! 
Front: The price will now be 10 

我有什麼改變,所以我既可以orderorder_price同步更新?

回答

2

分配=意指接受一個參數將被分配(或相同數量的元素如在平行分配的事件變量)

你可以這樣做的:

def order=(args) 
    @order = args[0] 
    @order_price = args[1] 
    notify_observers 
end 

然後CAL升像

igg.order=["yummy butter donut", 15] 

或使用選項Hash的建議@BartekGladys但兩種方案似乎糟糕,會犯錯誤,至少可以說,將需要該方法的內部的知識,以便正確地使用它。

目前即使這種方法的工作,將來你或任何人看着你的代碼庫,因爲你有一個實例變量@order所以假設將order=(val)將分配該變量將非常混亂。

如果您接受orderorder_price的方法change_order,您會更好,這樣可以消除關於發生什麼的所有混淆。

def change_order(new_order, new_price) 
    @order = new_order 
    @order_price = new_price 
    notify_observers 
end 

然後閱讀它也更有意義。

igg = Customer.new("Iggy", "Bacon Donut", 10) 
#Currently seems like it is assigning order to an Array maybe? 
igg.order=("yummy butter donut", 15) 
#New much clearer as to the implementation and purpose of changing an order 
igg.change_order("yummy butter donut", 15) 
+0

這樣一個簡單的解決方案!爲什麼我沒有想到這個?謝謝!!另外,感謝您指出'='只能接受1個參數。我以前不知道。這些知識將派上用場:) – Iggy

1

這是非常奇怪的錯誤,但我找到可以幫助你的解決方案。您可以使用一個參數並在其中包含2個值。

def order=(opts={}) 
    @order = opts[:new_order] 
    @order_price = opts[:new_price] 
    notify_observers 
end 

和調用該函數:

igg.order= {new_order: 'yumyy better donut', new_price: 15 } 
+0

這很合理!之前沒有想過使用哈希。謝謝! – Iggy

相關問題