Рефакторинг Rubocop Style / GuardClause в более удобочитаемом и понятном виде - PullRequest
0 голосов
/ 13 июня 2018

Rubocop жалуется: Style / GuardClause: используйте предложение guard вместо того, чтобы заключать код в условное выражение.Если 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

и из чтения документов , кажется, что я могурешить эту проблему, реализовав вместо этого следующий код:

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 рефакторированногокод выше).

Есть ли лучший способ реорганизовать это, чтобы можно было добавить больше условий после кода ниже, без преждевременного возврата кода?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Я бы, вероятно, выделил большую часть метода как рядовые с четкими именами, указывающими на намерение.Реализация псевдокода будет выглядеть следующим образом:

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
0 голосов
/ 13 июня 2018

Я думаю, что мы можем сделать что-то вроде ниже

# 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

Структура защиты используется для отправки управления из блока, поэтому, если вам нужно что-то изменить или сделать что-то после условия, вы не сможетеиспользовать пункт охраны.Посмотрите на приведенный ниже код в таких сценариях, мы не будем использовать охранное предложение

def test
  if something_here?
    do_something
  end

  do_something_else
  do_something_else1
  do_something_else2
end
...