Чистая архитектура. Искусство разработки программного обеспечения. Роберт Мартин
Чтение книги онлайн.
Читать онлайн книгу Чистая архитектура. Искусство разработки программного обеспечения - Роберт Мартин страница 28
Фабрики
Чтобы соблюсти все эти правила, необходимо предусмотреть особый способ создания изменчивых объектов. Это объясняется тем, что практически во всех языках создание объектов связано с образованием зависимостей на уровне исходного кода от конкретных определений этих объектов.
В большинстве объектно-ориентированных языков, таких как Java, для управления подобными нежелательными зависимостями можно использовать шаблон «Абстрактная фабрика».
Рисунок 11.1 демонстрирует, как работает такая схема. Приложение Application
использует конкретную реализацию ConcreteImpl
через интерфейс Service
. Однако приложению требуется каким-то образом создавать экземпляры ConcreteImpl
. Чтобы решить эту задачу без образования зависимости от ConcreteImpl
на уровне исходного кода, приложение вызывает метод makeSvc
интерфейса фабрики ServiceFactory
. Этот метод реализован в классе ServiceFactoryImpl
, наследующем ServiceFactory
. Эта реализация создает экземпляр ConcreteImpl
и возвращает его как экземпляр интерфейса Service
.
Рис. 11.1. Использование шаблона «Абстрактная фабрика» для управления зависимостями
Извилистая линия на рис. 11.1 обозначает архитектурную границу. Она отделяет абстракцию от конкретной реализации. Все зависимости в исходном коде пересекают эту границу в одном направлении – в сторону абстракции.
Извилистая линия делит систему на два компонента: абстрактный и конкретный. Абстрактный компонент содержит все высокоуровневые бизнес-правила приложения. Конкретный компонент содержит детали реализации этих правил.
Обратите внимание, что поток управления пересекает извилистую линию в направлении, обратном направлению зависимостей в исходном коде. Зависимости следуют в направлении, противоположном направлению потока управления – именно поэтому принцип получил название принципа инверсии зависимости.
Конкретные компоненты
Конкретный компонент ConcreteImpl
на рис. 11.1 имеет единственную зависимость, то есть он нарушает принцип DIP. Это нормально. Полностью устранить любые нарушения принципа инверсии зависимости невозможно, но их можно сосредоточить в узком круге конкретных компонентов и изолировать от остальной системы.
Большинство систем будет содержать хотя бы один такой конкретный компонент – часто с именем main, потому что включает функцию main
[25]. В схеме, изображенной на рис. 11.1, функция main
могла бы создавать экземпляр ServiceFactoryImpl
и сохранять ссылку на него в глобальной переменной типа ServiceFactory
. Благодаря этому приложение Application
сможет использовать данную глобальную переменную для обращения к фабрике.
Заключение
По мере продвижения вперед и знакомства с высокоуровневыми архитектурными принципами мы снова и снова будем сталкиваться с принципом инверсии зависимостей. Он будет самым заметным организационным принципом
25
То есть функцию, которая вызывается операционной системой в момент запуска приложения.