以更 readable/maintainable 的方式重构 Rubocop Style/GuardClause
Refactoring Rubocop Style/GuardClause in a more readable/maintainable way
Rubocop 抱怨: Style/GuardClause:使用保护子句而不是将代码包装在条件表达式中。
如果 issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
^^
我的原码是
if issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
并且通过阅读 docs,我似乎可以通过实施以下代码来解决这个问题:
return unless issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
我可以看出,除非满足条件,否则这基本上会提前从方法中中断,但对我来说,这似乎不太可读。它似乎也不太易于维护,因为不能在此代码之后添加进一步的条件,除非它们在第一行传递条件,例如,如果 issue_flag == true && !issue_notification_sent
执行其他操作(任何匹配此条件的内容都已经在第 1 行返回)上面的重构代码)。
是否有更好的方法来重构它,以便可以在下面的代码之后添加更多条件,而不会过早返回代码?
谢谢。
我想我们可以做如下的事情
# issue_flag is boolean so we can directly put it
# create a new method with all the condition and give a proper name
return unless issue_flag && send_follow_up? # change name accourdingly
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
# document its behaviour
def send_follow_up?
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
guard 结构用于将控制发送到块之外,因此如果您需要更改某些内容或在条件之后执行某些操作,那么您将无法使用 guard 子句。看看下面的代码,在这种情况下我们不会使用保护子句
def test
if something_here?
do_something
end
do_something_else
do_something_else1
do_something_else2
end
我可能会将方法的大部分提取为私有方法,并使用清晰的名称来说明意图。伪代码实现如下所示:
def method_name
return unless flag? && issue_notification_sent_with_follow_up
log_follow_up
UserMailer.issue_notification(self, @email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
private
def flag?
issue_flag == true
end
def issue_notification_sent_with_follow_up
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
def log_follow_up
@email_address = "sales@test.com"
puts "Emailing Follow Up #{@email_address} - #{sales_order}"
end
Rubocop 抱怨: Style/GuardClause:使用保护子句而不是将代码包装在条件表达式中。 如果 issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up ^^
我的原码是
if issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
并且通过阅读 docs,我似乎可以通过实施以下代码来解决这个问题:
return unless issue_flag == true && issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
我可以看出,除非满足条件,否则这基本上会提前从方法中中断,但对我来说,这似乎不太可读。它似乎也不太易于维护,因为不能在此代码之后添加进一步的条件,除非它们在第一行传递条件,例如,如果 issue_flag == true && !issue_notification_sent
执行其他操作(任何匹配此条件的内容都已经在第 1 行返回)上面的重构代码)。
是否有更好的方法来重构它,以便可以在下面的代码之后添加更多条件,而不会过早返回代码?
谢谢。
我想我们可以做如下的事情
# issue_flag is boolean so we can directly put it
# create a new method with all the condition and give a proper name
return unless issue_flag && send_follow_up? # change name accourdingly
email_address = "sales@test.com"
puts "Emailing Follow Up #{email_address} - #{sales_order}"
UserMailer.issue_notification(self, email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
# document its behaviour
def send_follow_up?
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
guard 结构用于将控制发送到块之外,因此如果您需要更改某些内容或在条件之后执行某些操作,那么您将无法使用 guard 子句。看看下面的代码,在这种情况下我们不会使用保护子句
def test
if something_here?
do_something
end
do_something_else
do_something_else1
do_something_else2
end
我可能会将方法的大部分提取为私有方法,并使用清晰的名称来说明意图。伪代码实现如下所示:
def method_name
return unless flag? && issue_notification_sent_with_follow_up
log_follow_up
UserMailer.issue_notification(self, @email_address).deliver_now
update(issue_notification_follow_up_sent: true)
end
private
def flag?
issue_flag == true
end
def issue_notification_sent_with_follow_up
issue_notification_sent && !issue_notification_follow_up_sent && send_follow_up
end
def log_follow_up
@email_address = "sales@test.com"
puts "Emailing Follow Up #{@email_address} - #{sales_order}"
end