Роберт Мартин

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


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

интерфейсов. Это следствие сводится к набору очень простых правил:

       Не ссылайтесь на изменчивые конкретные классы. Ссылайтесь на абстрактные интерфейсы. Это правило применимо во всех языках, независимо от устройства системы типов. Оно также накладывает важные ограничения на создание объектов и определяет преимущественное использование шаблона «Абстрактная фабрика».

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

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

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

      Фабрики

      Чтобы соблюсти все эти правила, необходимо предусмотреть особый способ создания изменчивых объектов. Это объясняется тем, что практически во всех языках создание объектов связано с образованием зависимостей на уровне исходного кода от конкретных определений этих объектов.

      В большинстве объектно-ориентированных языков, таких как Java, для управления подобными нежелательными зависимостями можно использовать шаблон «Абстрактная фабрика».

      Рисунок 11.1 демонстрирует, как работает такая схема. Приложение Application использует конкретную реализацию ConcreteImpl через интерфейс Service. Однако приложению требуется каким-то образом создавать экземпляры ConcreteImpl. Чтобы решить эту задачу без образования зависимости от ConcreteImpl на уровне исходного кода, приложение вызывает метод makeSvc интерфейса фабрики ServiceFactory. Этот метод реализован в классе ServiceFactoryImpl, наследующем ServiceFactory. Эта реализация создает экземпляр ConcreteImpl и возвращает его как экземпляр интерфейса Service.

      Рис. 11.1. Использование шаблона «Абстрактная фабрика» для управления зависимостями

      Извилистая линия на рис. 11.1 обозначает архитектурную границу. Она отделяет абстракцию от конкретной реализации. Все зависимости в исходном коде пересекают эту границу в одном направлении – в сторону абстракции.

      Извилистая линия делит систему на два компонента: абстрактный и конкретный. Абстрактный компонент содержит все высокоуровневые бизнес-правила приложения. Конкретный компонент содержит детали реализации этих правил.

      Обратите внимание,