Нарушают ли проверенные исключения принцип «открыто-закрыто»?

У меня есть два проверенных исключения: TestException1 и TestException2 и следующий код:

void p1() throws TestException1{
    p2();
}

void p2() throws TestException1 { 
    p3();
}

void p3() throws TestException1 {}

Нарушает ли редактирование подписи p3 следующим образом принцип Open-Closed?

void p3() throws TestException1, TestException2 {}

person Overflow 404    schedule 26.02.2019    source источник
comment
Есть какие-то аргументы, почему это может быть?   -  person daniu    schedule 26.02.2019
comment
Потому что p3() закрыт для расширения. Любое расширение (в данном случае добавление нового проверенного исключения в throw) p3 подразумевает редактирование сигнатур p2() и p1().   -  person Overflow 404    schedule 26.02.2019
comment
О, я не видел, чтобы p2 назывался p3. Я бы не назвал добавление исключений к существующему методу нарушением принципа Open-Closed, поскольку это не так сильно влияет на дизайн программного обеспечения, как на совместимость версий, что больше касается архитектуры.   -  person daniu    schedule 26.02.2019


Ответы (2)


Кажется, теперь я понимаю, что вы имеете в виду под своим вопросом. (2-я попытка)

Строго говоря, любое изменение, которое вы вносите в исходный код класса, нарушает закрытую часть принципа открытого и закрытого. Значимость нарушения зависит от характера изменения.

В вашем примере изменение проверенных исключений, выдаваемых общедоступным методом API в Java, является значительным нарушением. Это может привести к ошибкам компиляции в любом методе, который использует методы... или Error исключения подкласса, вызванные проблемами двоичной совместимости, если вы не перекомпилируете. Действительно, поскольку p3 вызывается p2 и косвенно p1, вам действительно нужно изменить больше класса, чтобы он скомпилировался. Это может увеличить область изменения API.

Итак, на ваш вопрос:

Нарушают ли проверенные исключения принцип «открыто-закрыто»?

Не совсем.

Проверенные исключения можно использовать, не нарушая принцип открытости-закрытости. Однако добавление проверенного исключения к замороженному методу API нарушает принцип1. Но нарушением является действие добавления исключения... а не само исключение или проверенные исключения в целом.


1 - И даже это спорно. Обратной стороной является то, что исправление недостатков дизайна и ошибок не нарушает принцип открытого и закрытого.

person Stephen C    schedule 27.02.2019
comment
Любое изменение, которое вы вносите в исходный код класса, нарушает закрытую часть, является слишком строгим. Бертран Мейер делает заметные исключения, например. Если у вас есть контроль над исходным программным обеспечением и вы можете переписать его таким образом, чтобы оно удовлетворяло потребности нескольких типов клиентов без дополнительных сложностей, вы должны это сделать. Кроме того, Ни -Закрытый принцип или переопределение в наследовании - это способ устранения недостатков дизайна, не говоря уже об ошибках. Если с модулем что-то не так, вы должны это исправить. - person jaco0646; 03.03.2019

Нет, проверенные исключения не нарушают OCP, т.к. по той простой причине, что OCP применяется к модулям, а не к методам.

Если вы считаете, что проверенное исключение — это просто еще одна часть сигнатуры метода, этот вопрос аналогичен вопросу о том, нарушают ли имена методов, параметры методов или возвращаемые типы методов OCP. Этот принцип просто не применим на таком детальном уровне.

Не зная, как реализуется метод или, что более важно, как метод раскрывается через API своего модуля, нам не о чем судить. Например, метод может полагаться на жестко закодированную константу; но если метод может быть переопределен клиентами, он по-прежнему открыт для расширения. Ничто о существовании проверенного исключения не сообщает нам, является ли модуль расширяемым.

С другой стороны, если проверенные исключения заставляют метод быть окончательным, и если такой метод предоставляется модулем как часть его общедоступного API, и если этот модуль не предоставляет альтернативы этому API, то это будет нарушением OCP.

person jaco0646    schedule 01.03.2019
comment
Это неправда. Мейер Бертран (1988) в своей книге «Объектно-ориентированное программное обеспечение» утверждает, что программные объекты (классы, модули, функции и т. д.) должны быть открыты для расширения, но закрыты для модификации. - person Overflow 404; 03.03.2019
comment
Пожалуйста, укажите номер страницы для цитаты. Я смотрю на второе издание книги 1997 года, которое, как мне кажется, превосходит оригинал. OCP определен на стр. 57-61. Он определяется последовательно с точки зрения модулей. Это предложение, скорее всего, взято из статьи Роберта Мартина 1995 года, где он перефразирует Мейера. Мартин дает более зрелое объяснение в своем связанном сообщении в блоге от 2014 года, в котором постоянно используются модули. - person jaco0646; 03.03.2019