Защитные оговорки и принцип единой ответственности (SRP)

В настоящее время читает фантастическую книгу «Практический объектно-ориентированный дизайн в Ruby» и работает над простым ката, чтобы действительно практиковать некоторые принципы, которые в ней обсуждаются.

У меня есть метод, который делает следующее:

def release_bike
  capacity_empty_error if empty?
  bike
end

Это «освобождает объект велосипеда» из моего класса DockingStation (я знаю, что объект велосипеда должен быть аргументом, но на данный момент я просто хочу, чтобы метод возвращал объект велосипеда, а не удалял его).

#capacity_empty_error делает следующее:

def capacity_empty_error
  raise "Docking Station is empty."
end

А #пусто? похоже:

def empty?
  bike == nil
end

Где bike — это метод-оболочка для моей переменной экземпляра @bike. Таким образом, текущая емкость класса DockingStation равна 1, так как код предполагает, что он заполнен, когда для #bike задано какое-то значение (позже я планирую добавить соответствующую емкость).

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

Я чувствую, что строка защитного предложения в #release_bike:

capacity_empty_error if empty?

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

Можно ли это сделать? Как другие добились этого?


person Joe    schedule 18.04.2016    source источник
comment
Я смотрю на это так: договор на release_bike такой, велосипед отпускаю и возвращаю. Но он не может этого сделать, если стойка пуста. SRP на самом деле требует, чтобы метод обрабатывал этот случай сам, что он решает сделать, вызвав исключение... вы, конечно, можете видеть это по-разному.   -  person Andy Jones    schedule 19.04.2016


Ответы (1)


Как насчет переноса функциональности в другие классы/модули?

module BikeChecker
  def capacity_empty_error
    raise "Docking Station is empty."
  end

  def release_bike
    capacity_empty_error if empty?
  end

  def empty?
    false
  end
end

class YourClass
  include BikeChecker

  def release_bike
    super
    bike
  end

  def empty?
    bike == nil
  end
end 

Вы можете отказаться от #пусто? метод от BikeChecker, я оставил его здесь для лучшего понимания

person Igor Pavlov    schedule 18.04.2016
comment
Ах! Я никогда не видел использования супер, большое спасибо Игорь. - person Joe; 18.04.2016