我认为您customer_name
自动生成的委托方法是目前最简单的方法。由于它是一个方法调用(而不是一系列方法链),因此以后很容易重构(或者,比某些链式方法更容易重构)
想象一下,无论出于何种原因,将许多客户添加到订单中,其中一个是主要客户。现在您的订单类可能看起来像
class Order < ActiveRecord::Base
has_many :customers
def customer_name
if customers.first.primary?
customers.first.name
else
customers.last.name
end
end
很容易用我们自己的一种方法替换方便委托生成的方法。
(第一次编写也非常容易,因为delegate
它会处理所有样板。很有可能你会customer_name
在你的应用程序中永远使用这种形式。很难知道。但是第一次编写很容易/自动编写的代码扔掉很便宜:))
当然,您必须避免编写方法名称的情况,例如customer_streetaddress_is_united_states?
(是的,不是将对象图编码为点,而是将其编码为下划线。)
如果您的视图确实需要知道用户是否位于美国,那么这样的方法可能会起作用:
class Order < ActiveRecord::Base
belongs_to :customer
def shipping_to_us?
customer.shipping_country == "USA"
# Law of Demeter violation would be:
# customer.addresses.first.country == "USA"
end
end
class Customer < ActiveRecord::Base
has_many :addresses
def shipping_country
addresses.first.country
end
end
请注意这里是如何向对象Order
询问Customer
送货地址,而不是告诉客户获取其客户的第一个地址所在的国家/地区。就像一个告诉你做某事并让你独自一人的老板与一个对你的日常工作进行微观管理的老板。(要获得额外的启发,请阅读问题,不要告诉 Ruby 开发的方法 :))
关于使用演示者、装饰器方法或助手来避免这些可能只是显示逻辑代码乱扔模型,有一些话要说。我将把它作为练习留给读者:)