如前所述,您的团队的代码覆盖率标准由您决定。你需要理解收益递减的论点和“你希望我不测试什么”的论点,然后打电话。
然而,你的问题还有一个不同的方面值得注意:
使用安全导航运算符的代码是否比不使用它的代码更复杂?
Ruby中添加了安全导航操作符,以减少
undefined method 'x' for nil:NilClass (NoMethodError)
因违反德米特定律而造成的错误。由于在ActiveRecord中将查询和子句附加在一起的方式,这些违规行为在Rails应用程序中很常见。从某种意义上说,运算符可以减少代码。而且,一般来说,代码越少,复杂性就越低。但是,让我们来看看这一方法和其他两种方法,并比较其复杂性。
如果我们将安全导航与旧的使用方式进行比较
&&
到第三种方式(使用
NullObject
图案):
# safe_navigation.rb
class Parent
def calculate_status
"in parent"
end
end
class Child
attr_reader :some_parent
def initialize(parent = nil)
@parent = parent
end
def status_with_safe_navigation
parent&.calculate_status
end
def status_with_conditional
parent && parent.calculate_status
end
def status_with_null_object
return "" unless parent
parent.calculate_status
end
end
我们从flog得到以下内容:
~/so > flog -am safe_navigation.rb
12.3: flog total
3.1: flog/method average
4.0: Child#status_with_conditional safe_navigation.rb:22-23
3.7: Child#status_with_null_object safe_navigation.rb:26-29
2.5: Child#status_with_safe_navigation safe_navigation.rb:18-19
2.2: Child#initialize safe_navigation.rb:14-15
因此,是的,孤立地说,安全导航操作员是最不复杂的解决方案。但是,当您认为
Child
类现在还必须处理
nil
,整体复杂性场景发生变化。让我们添加一个
ClientOfChild
分类并查看其中的复杂性:
这是课程:
class ClientOfChild
def call_status_with_safe_navigation
result = Client.new.status_with_safe_navigation
result.nil? ? "" : result
end
def call_status_with_conditional
result = Client.new.status_with_conditional
result.nil? ? "" : result
end
def call_status_with_null_object
Client.new.status_with_null_object
end
end
在该代码中,带有和不带有安全导航操作员的代码必须处理
无
,但是
虚拟对象
基于代码则不然。
下面是鞭笞:
~/so > flog -am safe_navigation.rb
22.4: flog total
3.2: flog/method average
4.0: Child#status_with_conditional safe_navigation.rb:22-23
3.8: ClientOfChild#call_status_with_safe_navigation safe_navigation.rb:34-37
3.8: ClientOfChild#call_status_with_conditional safe_navigation.rb:40-43
3.7: Child#status_with_null_object safe_navigation.rb:26-29
2.5: Child#status_with_safe_navigation safe_navigation.rb:18-19
2.4: ClientOfChild#call_status_with_null_object safe_navigation.rb:46-47
2.2: Child#initialize safe_navigation.rb:14-15
现在,看看每条路径的总flog,我们得到:
* With safe navigation = 2.5 + 3.8 = 6.3
* With conditional = 4.0 + 3.8 = 7.8
* With NullObject = 3.7 + 2.4 = 6.1
因为这是对真实代码的过度简化,所以flog中的差异很小。但是,总的赢家是
虚拟对象
图案你会发现,方法越复杂,这些数字就会增长得越远。
出于这个原因,为了不违反代码中的德米特定律,我选择
虚拟对象
模式,而不是使用安全导航操作符(除了在ActiveReccord查询中,因为,嗯…Rails)。