Новый вариант использования работает, но наверняка реализован не так, как вам хотелось бы. Нечто подобное я видел во многих командах, которые посещал как консультант, и обычно это проявляется, когда команды начинают выяснять, как выглядит база кода, часто в первый раз.
В такой ситуации необходимо установить правило — архитектурный принцип, — которое гласит, например: «Веб-контроллеры никогда не должны обращаться к хранилищу непосредственно». Проблема, конечно, заключается в исполнении правила. Многие команды, с которыми я встречался, заявляли: «Мы обеспечиваем соблюдение этого принципа строгой дисциплиной и обзорами кода, потому что доверяем нашим разработчикам». Это хорошо, что есть такая уверенность, но все мы знаем, что происходит, когда бюджет и сроки начинают приближаться к концу.
Намного меньше команд сообщали мне, что они используют инструменты статического анализа (например, NDepend, Structure101, Checkstyle) для автоматической проверки и выявления архитектурных нарушений во время сборки. Возможно, вы уже видели такие правила; обычно они имеют форму регулярных выражений или строк с шаблонными символами, которые указывают: «типы в пакете **/web не должны использоваться типами в **/data» и проверяются после этапа компиляции.
Это немного грубоватый подход, но он может помочь, сообщая о нарушениях архитектурных принципов, которые (по вашему мнению) должны помешать вашей команде разработчиков выполнить сборку. Проблема обоих подходов в том, что они чреваты ошибками и цикл обратной связи дольше, чем хотелось бы. Если отключить проверку, в результате код может превратиться в «большой ком грязи» [69] http://www.laputan.org/mud /.
. Лично я хотел бы, чтобы за соблюдением архитектурных принципов следил компилятор.
Это ведет нас к варианту «упаковка по компонентам». Цель этого гибридного подхода, обсуждавшегося до сих пор, — упаковать все обязанности, связанные с одним крупным компонентом, в единый Java-пакет. Речь идет о сервис-ориентированном представлении программной системы, что, собственно, мы наблюдаем в архитектурах микрослужб. Подобно портам и адаптерам, интерпретирующим Веб как всего лишь еще один механизм доставки, методика «упаковка по компонентам» помогает отделить пользовательский интерфейс от этих крупных компонентов. На рис. 34.6 показано, как мог бы выглядеть вариант «просмотр заказов».
По сути, этот подход связывает «бизнес-логику» и код для работы с хранилищем в единое нечто, что мы называем «компонентом». Выше в книге дядюшка Боб дал такое определение компонента:
Компоненты — это единицы развертывания. Они представляют наименьшие сущности, которые можно развертывать в составе системы. В Java — это jar-файлы.
Рис. 34.6.Вариант использования «просмотр заказов»
Мое определение компонента немного отличается: «Группа функциональных возможностей, находящихся за общим чистым интерфейсом, которые постоянно находятся внутри среды выполнения, такой как приложение». Это определение взято из описания модели C4 программной архитектуры («C4 software architecture model») [70] Дополнительные сведения можно найти по адресу https://www.structurizr.com/help/c4 .
, которая определяет простую иерархическую организацию статических структур программной системы в терминах контейнеров, компонентов и классов (или кода). В этом описании говорится, что программная система состоит из одного или нескольких контейнеров (например, веб-приложений, мобильных приложений, обычных приложений, баз данных, файловых систем), каждый из которых содержит один или несколько компонентов, которые, в свою очередь, реализуются одним или несколькими классами (или кодом). Находится ли каждый компонент в отдельном jar-файле — это уже второстепенный вопрос.
Ключевое преимущество подхода «упаковки по компонентам» заключается в размещении всего кода, например, имеющего отношение к обработке заказов, в одном месте — в компоненте OrdersComponent. Задачи внутри компонента все еще разделены, то есть бизнес-логика отделена от функций доступа к хранилищу, но это разделение является уже деталью реализации компонентов, о которой потребителям знать не обязательно. Это напоминает организацию микрослужб или сервис-ориентированную архитектуру, когда имеется отдельная служба OrdersService, инкапсулирующая все, что связано с обработкой заказов, отличаясь лишь режимом разделения.
Читать дальше
Конец ознакомительного отрывка
Купить книгу