Чтение онлайн

на главную - закладки

Жанры

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

Именно так работает принцип открытости/закрытости на архитектурном уровне. Архитекторы разделяют функциональные возможности, опираясь на то, как, почему и когда их может потребоваться изменить, и затем организуют их в иерархию компонентов. Компоненты, находящиеся на верхних уровнях в такой иерархии, защищаются от изменений в компонентах на нижних уровнях.

Управление направлением

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

Например, интерфейс

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

Сокрытие информации

Интерфейс заказчика финансового отчета служит другой цели – защитить контроллер финансового отчета от необходимости знать внутренние особенности интерактора. В отсутствие этого интерфейса контроллер получил бы транзитивные зависимости от финансовых сущностей.

Транзитивные (переходящие) зависимости нарушают общий принцип, согласно которому программные сущности не должны зависеть от того, что они не используют непосредственно. Мы вновь встретимся с этим принципом, когда будем обсуждать принципы разделения интерфейсов и совместного повторного использования (Common Reuse Principle; CRP).

Поэтому, даже при том, что высший приоритет имеет защита интерактора от изменений в контроллере, мы также должны защитить контроллер от изменений в интеракторе, скрыв детали реализации интерактора.

Заключение

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

9. Принцип подстановки Барбары Лисков

В 1988 году Барбара Лисков написала следующие строки с формулировкой определения подтипов.

Здесь требуется что-то вроде следующего свойства подстановки: если для каждого объекта o1 типа S существует такой объект o2 типа T, что для всех программ P, определенных в терминах T, поведение P не изменяется при подстановке o1 вместо o2, то S является подтипом T [24] .

Чтобы понять эту идею, известную как принцип подстановки Барбары Лисков (Liskov Substitution Principle; LSP), рассмотрим несколько примеров.

24

Barbara Liskov. Data Abstraction and Hierarchy, SIGPLAN Notices 23, 5 (May 1988).

Руководство по использованию наследования

Представьте,

что у нас есть класс с именем
License
, как показано на рис. 9.1. Этот класс имеет метод с именем
calcFee
, который вызывается приложением
Billing
. Существует два «подтипа» класса
License:
PersonalLicense
и
BusinessLicense
. Они реализуют разные алгоритмы расчета лицензионных отчислений.

Рис. 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.

Поделиться:
Популярные книги

Морозная гряда. Первый пояс

Игнатов Михаил Павлович
3. Путь
Фантастика:
фэнтези
7.91
рейтинг книги
Морозная гряда. Первый пояс

Лейб-хирург

Дроздов Анатолий Федорович
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Лейб-хирург

Прометей: каменный век

Рави Ивар
1. Прометей
Фантастика:
альтернативная история
6.82
рейтинг книги
Прометей: каменный век

Приручитель женщин-монстров. Том 4

Дорничев Дмитрий
4. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 4

Бесноватый Цесаревич

Яманов Александр
Фантастика:
альтернативная история
7.00
рейтинг книги
Бесноватый Цесаревич

Тринадцатый IV

NikL
4. Видящий смерть
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Тринадцатый IV

Гром над Империей. Часть 4

Машуков Тимур
8. Гром над миром
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Гром над Империей. Часть 4

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Генерал-адмирал. Тетралогия

Злотников Роман Валерьевич
Генерал-адмирал
Фантастика:
альтернативная история
8.71
рейтинг книги
Генерал-адмирал. Тетралогия

Ратник

Ланцов Михаил Алексеевич
3. Помещик
Фантастика:
альтернативная история
7.11
рейтинг книги
Ратник

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Отмороженный 10.0

Гарцевич Евгений Александрович
10. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 10.0

Действуй, дядя Доктор!

Юнина Наталья
Любовные романы:
короткие любовные романы
6.83
рейтинг книги
Действуй, дядя Доктор!

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6