mig*_*igu 7 oop ruby-on-rails law-of-demeter
德米特定律似乎是一个非常强大的概念.我可以理解它如何帮助编写良好且可维护的面向对象的代码.
有些人建议每次需要访问视图中关联对象的属性时编写委托方法.而不是在视图中写这样的东西
@order.customer.name
Run Code Online (Sandbox Code Playgroud)
你会写这段代码:
# model
class Order < ActiveRecord::Base
belongs_to :customer
delegate :name, :to => :customer, :prefix => true
end
#view
@order.customer_name
Run Code Online (Sandbox Code Playgroud)
另一方面,人们认为你的观点不应该指示模型,你不应该只为了在视图中交换下划线的点而向模型添加委托等方法.
如果在视图中违反Demeter法则,在模型中编写委托方法是否被认为是最佳实践?
我看到你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
Run Code Online (Sandbox Code Playgroud)
很容易用我们自己的方法替换那个方便委托生成的方法.
(第一次编写它也非常容易,因为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
Run Code Online (Sandbox Code Playgroud)
注意这里是如何Order
要求的Customer
对象的送货地址,VS 告诉客户得到它的客户的首地址的国家.就像一个告诉你做某事的老板,让你独自与老板一样,微观管理你日常工作的方式.(有关额外的启发,请阅读问题,不要告诉Ruby开发的方法:))
关于使用演示者,装饰器方法或帮助器,可以说有一些东西可以避免让这个可能只是显示逻辑代码乱丢你的模型.我会把它作为读者的练习:)
归档时间: |
|
查看次数: |
634 次 |
最近记录: |