Переопределение метода и соблюдение принципов SOLID

У меня есть родительский класс и дочерний класс следующим образом:

class Request {
  public function handleException() : array {
    throw new Exception( 'RequestException' );
  }
}
class SpecialRequest extends Request {
  public function handleException() : array {
    if (condition) {
      return [];
    }
    parent::handleException();
  }
}

У меня есть 2 класса запросов и метод handleException, который предназначен для возврата массива. Моя идея состоит в том, что родительский класс будет генерировать только исключения (потому что он не знает, как с ними обращаться). В то время как дочерним классам будет разрешено переопределять родительский метод для обработки определенных случаев и генерировать родительское исключение в противном случае.

Следуя принципам SOLID, я не должен менять сигнатуры методов при переопределении. Но глядя на родительский метод, кажется странным, что метод имеет тип возвращаемого значения массива, когда он просто генерирует исключение.

Что-то не так с классами?


person gerky    schedule 30.06.2020    source источник
comment
Если вы объявите Request::handleException() abstract, сделает ли этот метод менее странным? Вы фактически заставляете каждый наследующий класс реализовать свою собственную обработку исключения, что должно быть сделано в любом случае, если Request сам не знает, как обрабатывать исключение.   -  person noam    schedule 30.06.2020


Ответы (2)


Эта реализация в классе Request выглядит так, как будто она должна была вызвать исключение NotImplementedException. Однако обычно это огромный запах кода, указывающий на плохую абстракцию. Как если бы у вас была игрушечная собака и настоящая собака, реализующая один и тот же интерфейс, потому что они обе собаки с методом acceptBatteries. Игрушечная собака примет батарейки, а настоящая собака выдаст исключение. Просто плохая абстракция — нарушение LSP.

РЕДАКТИРОВАТЬ: если класс запроса был абстрактным, а метод обработки исключения был абстрактным.

person Michal Kováčik    schedule 30.06.2020
comment
Я обновил вопрос, поэтому моя идея заключается в том, что базовый класс будет генерировать только исключения (потому что он не знает, как с ними обращаться). В то время как дочерним классам будет разрешено переопределять родительский метод для обработки определенных случаев и генерировать родительское исключение в противном случае. - person gerky; 30.06.2020
comment
Тогда не используйте суперкласс, а скорее интерфейс. Это ясно сообщает, что этот метод не реализован. Проверить принцип разделения интерфейса - person Michal Kováčik; 02.12.2020

Request::handleException() должен быть объявлен абстрактным, поскольку родительский класс является абстрактным

Каждый подкласс листа должен переопределять его

person McSee    schedule 22.01.2021