Чистая архитектура. Искусство разработки программного обеспечения. Роберт Мартин

Чтение книги онлайн.

Читать онлайн книгу Чистая архитектура. Искусство разработки программного обеспечения - Роберт Мартин страница 25

Чистая архитектура. Искусство разработки программного обеспечения - Роберт Мартин Библиотека программиста (Питер)

Скачать книгу

target="_blank" rel="nofollow" href="#i_031.jpg"/>

      Рис. 9.1. Класс License и его производные, соответствующие принципу LSP

      Этот дизайн соответствует принципу подстановки Барбары Лисков, потому что поведение приложения Billing не зависит от использования того или иного подтипа. Оба подтипа могут служить заменой для типа License.

      Проблема квадрат/прямоугольник

      Классическим примером нарушения принципа подстановки Барбары Лисков может служить известная проблема квадрат/прямоугольник (рис. 9.2).

      Рис. 9.2. Известная проблема квадрат/прямоугольник

      В этом примере класс Square (представляющий квадрат) неправильно определен как подтип класса Rectangle (представляющего прямоугольник), потому что высоту и ширину прямоугольника можно изменять независимо; а высоту и ширину квадрата можно изменять только вместе. Поскольку класс User полагает, что взаимодействует с экземпляром Rectangle, его легко можно ввести в заблуждение, как демонстрирует следующий код:

      Rectangle r =…

      r. setW(5);

      r. setH(2);

      assert(r.area() == 10);

      Если на место… подставить код, создающий экземпляр Square, тогда проверка assert потерпит неудачу. Единственный способ противостоять такому виду нарушений принципа LSP – добавить в класс User механизм (например, инструкцию if), определяющий ситуацию, когда прямоугольник фактически является квадратом. Так как поведение User зависит от используемых типов, эти типы не являются заменяемыми (совместимыми).

      LSP и архитектура

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

      Подразумеваемые интерфейсы могут иметь множество форм. Это могут быть интерфейсы в стиле Java, реализуемые несколькими классами. Или это может быть группа классов на языке Ruby, реализующих методы с одинаковыми сигнатурами. Или это может быть набор служб, соответствующих общему интерфейсу REST.

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

      Лучший способ понять значение LSP с архитектурной точки зрения – посмотреть, что случится с архитектурой системы при нарушении принципа.

      Пример нарушения LSP

      Допустим, что мы взялись за создание приложения, объединяющего несколько служб, предоставляющих услуги такси. Клиенты, как предполагается, будут использовать наш веб-сайт для поиска подходящего такси, независимо от принадлежности к той или иной компании. Как только клиент подтверждает заказ, наша система передает его выбранному такси, используя REST-службу.

      Теперь предположим, что URI службы является частью информации, хранящейся в базе данных водителей. Выбрав водителя, подходящего

Скачать книгу