Перейти к основному содержимому

Введение в Структуризер

· 4 мин. чтения

1. Введение

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

Structurizr отказывается от традиционных подходов перетаскивания в редакторах архитектурных диаграмм, таких как UML, и позволяет нам описывать наши архитектурные артефакты с помощью инструмента, который мы знаем лучше всего: Java.

2. Начало работы

Для начала добавим зависимость structurizr-core в наш pom.xml:

<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-core</artifactId>
<version>1.0.0</version>
</dependency>

3. Системы

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

Во-первых, нам нужно создать рабочее пространство и модель :

Workspace workspace = new Workspace("Payment Gateway", "Payment Gateway");
Model model = workspace.getModel();

Мы также определяем пользователя и две программные системы в рамках этой модели:

Person user = model.addPerson("Merchant", "Merchant");
SoftwareSystem paymentTerminal = model.addSoftwareSystem(
"Payment Terminal", "Payment Terminal");
user.uses(paymentTerminal, "Makes payment");
SoftwareSystem fraudDetector = model.addSoftwareSystem(
"Fraud Detector", "Fraud Detector");
paymentTerminal.uses(fraudDetector, "Obtains fraud score");

Теперь, когда наша система определена, мы можем создать представление:

ViewSet viewSet = workspace.getViews();

SystemContextView contextView = viewSet.createSystemContextView(
paymentTerminal, "context", "Payment Gateway Diagram");
contextView.addAllSoftwareSystems();
contextView.addAllPeople();

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

4. Просмотр через PlantUML

В предыдущем разделе мы создали представление простого платежного шлюза.

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

StringWriter stringWriter = new StringWriter();
PlantUMLWriter plantUMLWriter = new PlantUMLWriter();
plantUMLWriter.write(workspace, stringWriter);
System.out.println(stringWriter.toString());

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

./88d16dd44bfd12519c5a68a26b27e23c.png

5. Просмотр через сайт Structurizr

Существует еще один вариант рендеринга диаграмм. Архитектурный вид можно отправить на веб-сайт Structurizr через клиентский API. Затем диаграмма будет сгенерирована с использованием их богатого пользовательского интерфейса.

Давайте создадим клиент API:

StructurizrClient client = new StructurizrClient("key", "secret");

Ключевые и секретные параметры получены из панели управления рабочей области на их веб-сайте. Затем на рабочую область можно ссылаться:

client.putWorkspace(1337, workspace);

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

6. Контейнеры

Давайте расширим нашу программную систему, добавив несколько контейнеров. В модели C4 контейнерами могут быть веб-приложения, мобильные приложения, настольные приложения, базы данных и файловые системы: почти все, что содержит код и/или данные.

Во-первых, мы создаем несколько контейнеров для нашего платежного терминала:

Container f5 = paymentTerminal.addContainer(
"Payment Load Balancer", "Payment Load Balancer", "F5");
Container jvm1 = paymentTerminal.addContainer(
"JVM-1", "JVM-1", "Java Virtual Machine");
Container jvm2 = paymentTerminal.addContainer(
"JVM-2", "JVM-2", "Java Virtual Machine");
Container jvm3 = paymentTerminal.addContainer(
"JVM-3", "JVM-3", "Java Virtual Machine");
Container oracle = paymentTerminal.addContainer(
"oracleDB", "Oracle Database", "RDBMS");

Затем мы определяем отношения между этими вновь созданными элементами:

f5.uses(jvm1, "route");
f5.uses(jvm2, "route");
f5.uses(jvm3, "route");

jvm1.uses(oracle, "storage");
jvm2.uses(oracle, "storage");
jvm3.uses(oracle, "storage");

Наконец, создайте представление контейнера, которое можно передать средству визуализации:

ContainerView view = workspace.getViews()
.createContainerView(paymentTerminal, "F5", "Container View");
view.addAllContainers();

Визуализация полученной диаграммы с помощью PlantUML дает:

./6a36824fdf25cd883222b3bb82b14705.png

7. Компоненты

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

Во-первых, мы создаем некоторые компоненты в контейнере:

Component jaxrs = jvm1.addComponent("jaxrs-jersey", 
"restful webservice implementation", "rest");
Component gemfire = jvm1.addComponent("gemfire",
"Clustered Cache Gemfire", "cache");
Component hibernate = jvm1.addComponent("hibernate",
"Data Access Layer", "jpa");

Далее, давайте добавим некоторые отношения:

jaxrs.uses(gemfire, "");
gemfire.uses(hibernate, "");

Наконец, давайте создадим представление:

ComponentView componentView = workspace.getViews()
.createComponentView(jvm1, JVM_COMPOSITION, "JVM Components");

componentView.addAllComponents();

Представление полученной диаграммы через PlantUML приводит к:

./14bb30e9f92d47721e729a2e490f3005.png

8. Извлечение компонентов

Для существующих баз кода, использующих среду Spring, Structurizr предоставляет автоматизированный способ извлечения компонентов с аннотациями Spring и добавления их к архитектурным артефактам.

Чтобы использовать эту функцию, нам нужно добавить еще одну зависимость:

<dependency>
<groupId>com.structurizr</groupId>
<artifactId>structurizr-spring</artifactId>
<version>1.0.0-RC5</version>
</dependency>

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

Мы даже можем подключить собственные стратегии разрешения:

ComponentFinder componentFinder = new ComponentFinder(
jvm, "com.foreach.structurizr",
new SpringComponentFinderStrategy(
new ReferencedTypesSupportingTypesStrategy()
),
new SourceCodeComponentFinderStrategy(new File("/path/to/base"), 150));

Наконец, мы запускаем искатель:

componentFinder.findComponents();

Приведенный выше код сканирует пакет com.foreach.structurizr на наличие bean-компонентов с аннотациями Spring и добавляет их в качестве компонентов в контейнер JVM. Излишне говорить, что мы можем реализовать свои собственные сканеры, аннотированные ресурсы JAX-RS и даже связыватели Google Guice.

Пример простой диаграммы из типового проекта воспроизводится ниже:

./c60e264a3911ed8b53b867fe943ab049.png

9. Заключение

В этом кратком руководстве рассматриваются основы проекта Structurizr for Java.

И, как всегда, пример кода можно найти на GitHub .