我正在研究Ruby的Design Pattern并且遇到了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
。但是,我希望能够更新两件事:order
和order_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
我需要更改哪些内容才能同时更新order
和order_price
?
答案 0 :(得分:2)
赋值=
用于接受要分配的单个参数。(或者在并行赋值的情况下,与变量的元素数相同)
你可以这样做:
def order=(args)
@order = args[0]
@order_price = args[1]
notify_observers
end
然后像
一样打电话igg.order=["yummy butter donut", 15]
或使用选项Hash
作为@BartekGladys建议但是这两种解决方案看起来都很糟糕且容易错误,并且需要了解方法的内部以便正确使用它。
此外,即使这种方法有效,但是对于未来您或任何查看您的代码库的人来说都会非常混乱,因为您有一个实例变量@order
所以假设order=(val)
会分配该变量。
使用change_order
接受order
和order_price
的方法会更好,这样可以消除所有关于发生的混乱。
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)
答案 1 :(得分: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 }