Обработка исключений в декораторе, нарушающем LSP - PullRequest
0 голосов
/ 24 июня 2019

В настоящее время я читаю книгу Марка Симана и Стивена ван Дёрсена «Внедрение зависимостей» (второе издание, но этот же пример приведен в первом издании).

В главе 9.2.2 «Сообщение об исключениях с использованием шаблона Decorator»он предлагает декоратор обработки исключений, который украшает абстракцию с перехватом определенных исключений и открытием окна предупреждения вместо всплытия исключения для потребителя.

Он заявляет, что придерживается SRP и OCP, за которыми я могу следовать.

Однако, на мой взгляд, это нарушает принцип замены Лискова .

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

По моему мнению, потребитель не должен знать, что абстракция была оформлена, он должен придерживаться контракта, который обеспечивает абстракция.

Мое предложение будетбыть новым интерфейсом IExceptionHandlingAbstraction, который реализован адаптером, который перехватывает исключения IAbstraction и преобразует его в окна предупреждений.Таким образом, потребитель может рассчитывать на контракт IExceptionHandlingAbstraction и явно знает, что ему не нужно обрабатывать исключения самостоятельно.

Поскольку я действительно очень доверяю сообщениям, ответам и книгам Марка, я не совсем уверен, смогу ли яя что-то здесь упускаю.

1 Ответ

0 голосов
/ 24 июня 2019

потребитель не должен знать, что абстракция была оформлена, он должен придерживаться договора, который обеспечивает абстракция.

Это правильно.Чтобы придерживаться LSP, обе реализации абстракции должны придерживаться одного и того же контракта.Но теперь возникает вопрос: что именно является контрактом?Что может ожидать потребитель.

В отличие от Java, .NET не вызывает исключения как часть определения метода.И я думаю, что это хорошо.Вы не можете и не должны ограничивать исключения, выбрасываемые в абстракцию.Это, конечно, меняется, когда вы генерируете исключения, которые клиент должен обрабатывать.В этом случае тип исключения должен быть частью контракта.

Большая проблема в этом конкретном примере декоратора, IMO, заключается в том, что исключение не всплывает.Это полностью проглочено.Это, безусловно, можно считать нарушением (неявного) контракта, поскольку разработчик может ожидать, что вызов завершится успешно, если не будет выдано исключение.Так что я согласен с тем, что пример немного наивный и нарушает LSP.

Однако этот пример не является полностью защищенным, на 100% ТВЕРДЫМ решением, а скорее как пример для демонстрацииСила перехвата с использованием декораторов.Также обратите внимание, что в главе 10 мы объясняем, что быть на 100% твердым не возможно и не желательно.Все дело в компромиссах, и, возможно, этот пример декоратора хорошо работает в конкретном клиентском приложении, которое вы создаете, хотя я ожидаю, что потребитель (форма) должен будет знать, успешно ли выполнена операция, потому что вы обычно хотите закрыть форму после ее завершения.,Но в этом случае я ожидаю, что лучшим решением будет дизайн, предусмотренный в главе 10.

Мое предложение будет новым интерфейсом IExceptionHandlingAbstraction, который реализуется адаптером, который перехватывает исключенияIAbstraction и преобразует его в блоки оповещений

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

...