Einführung in Structurizr

Einführung in Structurizr

1. Einführung

In diesem Artikel geht es um Structurizr, ein Tool, dasprogrammatic approach to architectural definitions and visualizations based on the C4 Model. bereitstellt

Structurizr unterbricht die traditionellen Drag-and-Drop-Ansätze von Architekturdiagramm-Editoren wie UML und ermöglicht es uns, unsere Architekturartefakte mit dem Tool zu beschreiben, das wir am besten kennen: Java.

2. Anfangen

Fügen Sie zunächst die Abhängigkeit vonstructurizr-corezu unserenpom.xml:hinzu


    com.structurizr
    structurizr-core
    1.0.0-RC5

3. Systeme

Beginnen wir mit der Modellierung einer Beispielarchitektur. Angenommen, wir bauen ein betrugserkennungsfähiges Zahlungsterminal, das von Händlern zum Abrechnen von Zahlungen verwendet wird.

Zuerst müssen wir einWorkspace und einModel erstellen:

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

Wir definieren auch einen Benutzer und zwei Softwaresysteme innerhalb dieses Modells:

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");

Nachdem unser System definiert ist, können wir eine Ansicht erstellen:

ViewSet viewSet = workspace.getViews();

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

Hier haben wir eine Ansicht erstellt, die alle Softwaresysteme und Personen umfasst. Jetzt muss die Ansicht gerendert werden.

4. Ansicht über PlantUML

Im vorherigen Abschnitt haben wir eine Ansicht eines einfachen Zahlungsgateways erstellt.

Der nächste Schritt ist die Erstellung eines menschenfreundlichen Diagramms. Die wahrscheinlich einfachste Lösung für eine Organisation, die bereitsPlantUML verwendet, besteht darin, Structurizr anzuweisen, einen PlantUML-Export durchzuführen:

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

Hier wird das resultierende Markup auf dem Bildschirm gedruckt, aber es kann genauso einfach in eine Datei gesendet werden. Wenn Sie die Daten auf diese Weise rendern, erhalten Sie das folgende Diagramm:

image

5. Ansicht über die Structurizr-Website

Eine weitere Option zum Rendern von Diagrammen ist vorhanden. Eine Architekturansicht kann über eine Client-API an die Structurizr-Website gesendet werden. Das Diagramm wird dann mithilfe der umfangreichen Benutzeroberfläche erstellt.

Lassen Sie uns einen API-Client erstellen:

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

Die wichtigsten und geheimen Parameter werden über das Arbeitsbereich-Dashboard auf der Website abgerufen. Auf den Arbeitsbereich kann dann verwiesen werden durch:

client.putWorkspace(1337, workspace);

Natürlich müssen wir uns auf der Website registrieren und einen Arbeitsbereich erstellen. Ein Basiskonto mit einem einzelnen Arbeitsbereich ist kostenlos. Gleichzeitig stehen auch kommerzielle Pläne zur Verfügung.

6. Behälter

Erweitern wir unser Softwaresystem um einige Container. In einem C4-Modell können Container Webanwendungen, mobile Apps, Desktopanwendungen, Datenbanken und Dateisysteme sein: so ziemlich alles, was Code und / oder Daten enthält.

Zuerst erstellen wir einige Container für unser Zahlungsterminal:

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");

Als Nächstes definieren wir Beziehungen zwischen diesen neu erstellten Elementen:

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

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

Erstellen Sie schließlich eine Containeransicht, die einem Renderer zugeführt werden kann:

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

Das Rendern des resultierenden Diagramms über PlantUML erzeugt:

image

7. Komponenten

Die nächste Detailebene im C4-Modell bietet die Komponentenansicht. Das Erstellen eines solchen ähnelt dem, was wir zuvor getan haben.

Zunächst erstellen wir einige Komponenten in einem Container:

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");

Als nächstes fügen wir einige Beziehungen hinzu:

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

Zum Schluss erstellen wir die Ansicht:

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

componentView.addAllComponents();

Eine Wiedergabe des resultierenden Diagramms über PlantUML führt zu:

image

8. Komponentenextraktion

Für vorhandene Codebasen, die das Spring-Framework verwenden, bietet Structurizr eine automatisierte Methode zum Extrahieren von mit Spring-Anmerkungen versehenen Komponenten und zum Hinzufügen dieser Komponenten zu den Architekturartefakten.

Um diese Funktion nutzen zu können, müssen wir noch eine weitere Abhängigkeit hinzufügen:


    com.structurizr
    structurizr-spring
    1.0.0-RC5

Als nächstes müssen wir einComponentFindererstellen, das mit einer oder mehreren Auflösungsstrategien konfiguriert ist. Auflösungsstrategien wirken sich beispielsweise auf die Komponenten aus, die dem Modell hinzugefügt werden, die Tiefe der Abhängigkeitsbaumdurchquerung usw.

Wir können sogar benutzerdefinierte Auflösungsstrategien einbinden:

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

Zum Schluss starten wir den Finder:

componentFinder.findComponents();

Der obige Code durchsucht das Paketcom.example.structurizr nach Beans mit Spring-Annotation und fügt sie der Container-JVM als Komponenten hinzu. Selbstverständlich können wir unsere eigenen Scanner, mit JAX-RS-Anmerkungen versehenen Ressourcen und sogar Google Guice-Ordner implementieren.

Ein Beispiel eines einfachen Diagramms aus einem Beispielprojekt ist im Folgenden wiedergegeben:

image

9. Fazit

Dieses kurze Tutorial behandelt die Grundlagen des Structurizr for Java-Projekts.

Und wie immer kann Beispielcodeover on GitHub gefunden werden.