问题描述
所以我知道一些我知道的不同方法,我想探索各种方法的优缺点,这些方法是:
So I know of a few different approaches that I am aware of and I want explore the advantages and disadvantages of the various ways for various criteria which are:
- 可读性
- 表现
- 易于调试
- OO 原则(低耦合高内聚)
明确使用来自 active support 的 try 方法
Explicitly using the try method from active support
person.try(:pet).try(:name).try(:upcase)
使用救援 nil
person.pet.name.upcase rescue nil
使用 &&运营商链
Using an && operator chain
person && person.pet && person.pet.name && person.pet.name.upcase
猴子修补 Object 类,参见 https://gist.github.com/thegrubbsian/3499234 为原始要点
Monkey patching the Object class, see https://gist.github.com/thegrubbsian/3499234 for the original gist
class Object
def try_all(*methods)
values = [self]
methods.each do |method|
value = values.last.try(method)
return nil if value.nil?
values << value
end
values.last
end
end
person.try_all(:pet, :name, :upcase)
不要有 nil 安全代码,而是在调用代码之前验证数据
Don't have nil safe code, instead validate the data before you call the code
#not a good implementation by any means
def person_has_pet_with_name? person
begin
return true if !person.pet.name.nil?
rescue
return false
end
end
person.pet.name.upcase if person_has_pet_with_name?(person)
推荐答案
我个人对猴子补丁的一般看法是,除非没有其他方法,否则不要这样做(如果我真的想要猴子补丁,我会三思而后行)).
除了 Rails 已经膨胀了很多对象.所以我更不建议自定义膨胀对象.
为什么不通过经典的委托方法避免违反德米特法则:
My personal opinion about monkey patching in general is do NOT do it unless there is no other way (and even than I think twice if I really want to monkey patch).
Besides Rails already bloated objects a lot. So I'd not suggest custom bloating objects even more.
Why not avoiding to break the law of Demeter by the classic delegator approach:
class Person
attr_accessor :pet
delegate :name_upcased, to: :pet,
prefix: true, allow_nil: true
end
class Pet
attr_accessor :name
def name_upcased
@name.upcase if @name
end
end
@person.try :pet_name_upcased
您还可以在 不要违反德米特法则! 和 Module#delegate.
至少我不会坚持 Object#try 只要一个简单的条件解决它,因为查看'try'的来源比条件成本更高.
You can also read about the law of Demeter at Do not break the law of Demeter! and Module#delegate.
At least I would not stick to Object#try as long as a simple condition solves it, because looking at the source of 'try' it is more costly than the condition.
这篇关于长的 nil 安全方法链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!