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

системы при нарушении принципа.

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

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

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

      Допустим, что для водителя с именем Bob адрес URI отправки заказа выглядит так:

      purplecab.com/driver/Bob

      Наша система добавит в конец этого URI информацию о заказе и пошлет его методом PUT:

      purplecab.com/driver/Bob

      /pickupAddress/24 Maple St.

      /pickupTime/153

      /destination/ORD

      Это явно означает, что все службы должны соответствовать общему интерфейсу REST. Они должны единообразно интерпретировать поля pickupAddress, pickupTime и destination.

      Теперь предположим, что компания такси Acme наняла несколько программистов, которые ознакомились со спецификацией недостаточно внимательно. Они сократили имя поля destination до dest. Компания Acme – крупнейшая компания такси в нашем регионе, и бывшая жена президента компании Acme вышла замуж за президента нашей компании, и… В общем, вы поняли. Что может произойти с архитектурой нашей системы?

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

      Решить поставленную задачу проще всего простым добавлением инструкции if в модуль, занимающийся пересылкой заказов:

      if (driver.getDispatchUri(). startsWith("acme.com"))…

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

      Например, представьте, что компания Acme добилась большого успеха, купила компанию Purple Taxi и объединенная компания решила сменить имя и адрес веб-сайта и объединить все системы оригинальных компаний. Получается, что теперь мы должны добавить еще одну инструкцию if для «purple»?

      Архитектор должен изолировать систему от ошибок, подобных этой, и добавить модуль, управляющий созданием команд доставки заказов в соответствии с параметрами, указанным для URI в базе данных с настройками. Настройки могли бы выглядеть как-то так:

      UPI

      Acme.com

      Формат команды

      /pickupAddress/%s/pickupTime/%s/dest/%s

      UPI

      *.*

      Формат команды

      /pickupAddress/%s/pickupTime/%s/destination/%s

      В результате архитектор вынужден добавить важный и сложный механизм из-за того, что интерфейсы не всех REST-служб оказались совместимыми.

      Заключение

      Принцип

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