2 Punkte von GN⁺ 2023-10-23 | 1 Kommentare | Auf WhatsApp teilen
  • Das C4-Modell ist ein entwicklerfreundlicher Ansatz zum Erstellen von Softwarearchitektur-Diagrammen, der komplexe Strukturen schrittweise aufteilt und sichtbar macht
  • Die Abstraktion steigt in der Reihenfolge software systems → containers → components → code ab und behandelt Architektur hierarchisch
  • Auch die Diagramme sind entlang der Struktur system context → container → component → code aufgebaut
  • Je nach Bedarf ergänzen system landscape-, dynamic- und deployment-Diagramme die Gesamtstruktur sowie Ausführungs- und Bereitstellungsperspektiven
  • Da der Ansatz notation independent und tooling independent ist und damit nicht an eine bestimmte Notation oder ein bestimmtes Tool gebunden ist, lässt er sich an bestehende Umgebungen anpassen

Aufbau des C4-Modells

Diagramme und Unabhängigkeit

  • Die grundlegenden Diagramme sind so aufgebaut, dass Architektur in unterschiedlichen Tiefen betrachtet werden kann
  • Ergänzende Diagramme füllen Perspektiven aus, die durch die Basisebenen allein nicht ausreichend abgedeckt werden
  • Das Modell ist notation independent und tooling independent, es erzwingt also weder eine bestimmte Notation noch eine bestimmte Tool-Auswahl
  • Als weiterführendes Material gibt es das im Juli 2019 bei „Agile on the Beach 2019“ aufgezeichnete Video Visualising software architecture with the C4 model sowie die Unterlagen The C4 model

1 Kommentare

 
GN⁺ 2023-10-23
Hacker-News-Kommentare
  • Das größte Problem von Architekturdiagrammen ist meines Erachtens, dass sie von der Codebase abweichen.
    Solche Diagramme müssen automatisch generiert werden. Andernfalls hat das Team keine Möglichkeit zu wissen, ob die gerade betrachtete Grafik den aktuellen Zustand des Systems korrekt wiedergibt.

    • Diagramme ähneln Textdokumenten; daher ist es meist schwierig, aus Code automatisch etwas Nützliches zu generieren, sofern es im Code kein zusätzliches Markup gibt, das angibt, was erzeugt werden soll.
      Diagramme zeigen eine bestimmte Perspektive, heben einige Merkmale hervor und lassen andere weg. Für dasselbe Objekt kann es mehrere Diagramme geben, die unterschiedliche Aspekte oder Szenarien beschreiben. Letztlich müssen auch Diagramme wie Textdokumente zusammen mit Code und Anwendungsarchitektur gepflegt und als regelmäßige Aufgabe des Change Managements behandelt werden.
    • Wegen der Code-Modell-Kluft funktioniert dieser Ansatz nicht gut.
      In vielen Projekten ist der Code nicht so organisiert wie das mentale Modell, und fast keine Sprache bietet eine Möglichkeit, das zu lösen. Auch das Markieren im Code per Kommentar hat dasselbe Problem wie Diagramme, Kommentare und Dokumentation aktuell zu halten.
    • Diagramme, die so banal sind, dass sie automatisch aus der Codebase generiert werden können, haben oft kaum zusätzlichen Wert geliefert.
    • Architekturdiagramme dokumentieren, wie Software aufgebaut sein soll.
      Sie zeigen nicht den Ist-Zustand, sondern den Zielzustand. Der Code sollte dem Diagramm folgen, nicht umgekehrt. Diagramme aus Code zu generieren ist nur dann sinnvoll, wenn man neuen Leuten in einem Projekt ohne Dokumentation helfen will; selbst dann erzeugt man sie einmal, entfernt anschließend das Rauschen, verfeinert sie und nutzt sie danach als Referenzdokument.
    • Im Gegenteil: Automatische Dokumentation nimmt Teams meines Erachtens die Fähigkeit, auf einer höheren Abstraktionsebene zu denken.
      High-Level-Diagramme sollten sich schnell erstellen und verwerfen lassen; was sie weglassen, ist genauso wichtig wie das, was sie zeigen.
  • C4 gefällt mir. Früher hielt ich Kontextdiagramme wie „User -{do their job}-> System-of-Record“ für nutzlos, inzwischen verstehe ich den Grund dafür.
    Wir entwickeln gerade mit erweiterten Teams ein neues Design für ein komplexes System mit C4. Beim Zeichnen der obersten Darstellung ist uns diesmal aufgefallen, dass es neben dem Web-UI auch eine Mobile App geben wird, die teilweise getrennt sein kann; wenn sie offline ist oder das Backend langsam ist und bestimmte Ergebnisse noch nicht vorliegen, müssen manche Abläufe elegant degradiert werden. Auf der nächsten Ebene führte das zu einer Arbeits-Queue und wiederum zurück zur UX, sodass wir klar benennen konnten, bei welchen Requests der Abschluss theoretisch unbegrenzt lange dauern kann. Irgendwann wären wir vermutlich darauf gekommen, aber die Analyse hat dieses Problem direkt in den Mittelpunkt gestellt. Und das alles, weil wir ein Diagramm „Remote-User --{Mobile Stuff}--> Backend“ zeichnen mussten. Welche Tools man verwendet, spielt keine Rolle; ich nutze zum Beispiel in draw.io Tabs für die einzelnen Ebenen. Wenn es konkreter wird, werde ich die unteren Ebenen in separate Dateien auslagern.

  • Ich verstehe auch die Ansicht, dass Diagramme kein formalisiertes System brauchen, aber C4 ist meines Erachtens ziemlich leichtgewichtig. Bis auf Code-Ebene gehe ich nicht hinunter.
    Trotzdem hat structurizr, das C4-Diagramme ausgibt, meine Produktivität deutlich gesteigert. Der Ansatz, aus einem einzigen Modell mehrere Ansichten mit unterschiedlichem Detaillierungsgrad zu erzeugen, ist hervorragend im Vergleich zu mermaid, plantuml und Ähnlichem, wo jedes Diagramm unabhängig immer wieder dieselben Komponenten definieren und neu definieren muss. Einen Branch zu erstellen, das Modell zu ändern und die Idee zu präsentieren, hat für mich sehr gut funktioniert.

    • Ich habe structurizr kurz ausprobiert, fand es aber viel zu unflexibel.
      Es gab keine Möglichkeit, Konzepte zu zeichnen, die nicht strikt zu C4 gehören. Zum Beispiel wollte ich zwei Komponenten in eine Box setzen, um auszudrücken, dass sie derzeit als ein einziger Service deployt werden, aber das war nicht möglich. Das heißt nicht, dass es absolut gesehen ein gutes Design wäre, aber dem Team hätte es beim Verständnis geholfen. Die Idee, Architektur formal zu beschreiben, ist gut, aber der Mangel an Anpassungsmöglichkeiten bei der Diagrammausgabe war zu mühsam.
    • Eine Stimme für structurizr. Dank des modellgetriebenen Ansatzes ist es viel einfacher, Diagramme mit dem Code konsistent zu halten.
      Man beschreibt die Architektur, und structurizr rendert die Diagramme.
    • Mermaid passt definitiv nicht gut zu der Textmenge und Textformatierung, die C4 erfordert.
      Es ist möglich, aber ziemlich umständlich, und wenn die Beschreibungen der Pfeile zwischen Boxen länger werden, bricht das automatische Layout schnell zusammen.
  • Ich sehe Softwarearchitektur eher als Sammlung von Designentscheidungen, die die Implementierung leiten.
    Meiner Erfahrung nach geben die meisten Softwarearchitekten Software Engineers Leitlinien und Struktur vor. Die Formulierung in der C4-Erklärung, „eine Karte des vorhandenen Codes auf mehreren Detailebenen zu erstellen“, klingt für mich aber anders. Ich verstehe nicht, warum man Code-Diagramme Softwarearchitektur nennt. Das ist doch buchstäblich Code-Ebene – wie kann das Architektur sein? Das ist ungefähr so, als wollte man den Schaltplan in einem Stecker in den Bauplan eines Hauses aufnehmen. Wenn es heißt, man „sollte Automatisierungswerkzeuge verwenden“, bedeutet das dann, eine bestehende Codebasis funktionsweise zu dokumentieren? Ich sehe nicht, wie das beim Entwerfen und Planen von Software nützlich sein soll. Eine Karte, die die Struktur bestehender Software beschreibt, kann interessant sein, aber wenn man über Design Patterns spricht, liefert man beim Singleton auch keine funktionsweise Karte der Implementierung. Es reicht zu sagen, dass ein Singleton- oder Repository-Pattern benötigt wird. Softwaredesign an sich gibt es ganz klar, und dieser Ansatz scheint für Design auch plausibel, aber meiner Erfahrung nach sind Softwaredesign, Implementierung und Architektur nicht dasselbe und werden auch nicht von denselben Leuten gemacht. Das wirkt eher wie Systemdesign; ein Softwarearchitekt würde wohl eher beraten, damit dieses Systemdesign guten Architekturprinzipien entspricht. Vielleicht bin ich da zu pedantisch.

    • Dem Teil, dass „Softwarearchitektur eine Sammlung von Designentscheidungen ist, die die Implementierung leiten“, stimme ich zu.
      Ich halte es für eine wesentliche Aufgabe von Softwarearchitektur, Entwickler so zu informieren, dass sie selbst Designentscheidungen treffen können, statt jedes Mal die Entscheidung an eine Autorität abzugeben. Wo Architektur endet und Entwicklung beginnt, ist allerdings sehr unterschiedlich. Ich denke, die Architektur selbst bestimmt, was aus Architektursicht wichtig ist. Wenn die Architektur entscheidet, dass bestimmte Low-Level-Details einer Anwendung wichtig sind, dann werden auch sie zu Architekturdetails. In der Praxis kontrolliert Architektur in den meisten Organisationen mindestens das High-Level-Design wie Komponenten, Kommunikationsmuster, APIs und eingesetzte Technologien. In manchen Organisationen reicht sie bis zu einzelnen Klassen hinunter. Nicht zu allen Klassen, sondern zu denen, die die Problemdomäne modellieren – insbesondere dann, wenn dieses Modell als Sprache über mehrere Projekte hinweg genutzt oder als gemeinsames Artefakt implementiert wird. C4 passt gut zu Organisationen, die über eine Liste von Anwendungen und Integrationsschnittstellen hinaus auch Strukturen auf niedrigerer Ebene als architektonische Belange betrachten.
    • Auf ein Haus übertragen wäre C4 ein High-Level-Bauplan des Hauses für Laien, ein detaillierter Bauplan für die ausführenden Firmen, Schaltpläne für Versorgungssysteme wie Elektrik und optional eine detaillierte Spezifikation aller Steckdosen und Einbauten.
      Im Grunde hat man für jede klar unterscheidbare oder nützliche Ebene eines Systems ein Diagramm. Wenn ein Diagramm auf Code-Ebene nötig ist, arbeitet man wahrscheinlich an etwas komplexem Maßgeschneidertem – oder man spezifiziert ein Design über, das man besser als Implementierungsdetail belassen würde.
    • Ich stimme bis zu einem gewissen Grad zu, dass man zwischen Softwarearchitektur, Design und Implementierung Grenzen ziehen sollte.
      Das ist ähnlich wie im realen Bauwesen, wo Architekten, Ingenieure und Bauleiter unterschiedliche Rollen haben. Mich interessiert, wo man bei Architektur, Design und Implementierung jeweils die Linien ziehen sollte und welche Belange dort behandelt werden sollten.
    • Ich frage mich, ob damit gemeint ist, dass „Softwarearchitektur einer Sammlung von Designentscheidungen entspricht“, oder dass sie „eine Sammlung von Designentscheidungen ist“.
  • Interessant, aber ich sehe nicht wirklich, dass es besonders viel hinzufügt.
    High-Level-Diagramme sind gut, aber man kann sie bereits erstellen, ohne eine Website zu einem schicken visuellen Modell zu lesen. Die Website räumt das im Grunde auch ein. Es stimmt sehr, dass es in der Branche UML, ArchiMate und SysML gibt, viele Teams sich aber für viel einfachere „Boxen und Linien“-Diagramme entscheiden. Sie scheint aber zu ignorieren, warum UML-Klassendiagramme komplett gescheitert sind. Es wird zwar anerkannt, dass niemand sie mag, aber das vierte C des Modells, Code, ist am Ende ein UML-Klassendiagramm. So etwas braucht man nicht. Man sollte einfach beliebige Diagramme klar zeichnen und die Pfeile beschriften. Die ersten drei Diagramme sind dafür sogar gute Beispiele.

    • So mache ich es auch. Ich zeichne Boxen und Linien dazwischen.
      Auch beim Nachdenken über neue Konzepte oder beim Brainstorming hilft das sehr, weil das Werkzeug nicht im Weg steht. Im Moment nutze ich Freeform; es ist sehr simpel, funktioniert aber gut. Man wählt zwei Objekte aus und klickt mit Cmd-Klick oder Rechtsklick auf „add connecting line“.
    • Der Traum, aus Diagrammen Code zu generieren, ist gescheitert, aber UML wird auf der Architektur-Kommandobrücke weiterhin viel verwendet.
      Erst vor ein paar Monaten habe ich wieder ein Architekturdokument fertiggestellt, das reichlich Klassendiagramme, Sequenzdiagramme und Use Cases enthielt.
    • In Unternehmensumgebungen funktioniert diese Art tatsächlich nicht gut.
      Die Boxen geraten leicht zu einer Mischung von Dingen auf unterschiedlichen Ebenen. Manche sind abstrakt, manche konkret, manche einfach willkürlich. Wenn man dann etwa größere Architekturteile wie eine Supply Chain zusammensetzen muss, muss man praktisch alles neu machen. Das verursacht viel Verschwendung, und niemand hat die Gesamtarchitektur ausreichend klar im Blick, was zu weiterer Verschwendung und Qualitätsproblemen führt. Seltsamerweise reagieren viele Engineers defensiv auf formellere Ansätze; vermutlich, weil es keinen unmittelbaren Nutzen gibt oder sie nie mit Architektur in großem Maßstab zu tun hatten und das Problem deshalb nicht sehen.
    • Wenn mehrere Personen viele Architekturgespräche führen und aus Diagrammen auch Erkenntnisse gewinnen wollen, werden strukturierte Architekturkonventionen wichtiger.
  • Das zeigt, dass Software Engineering noch ein unreifes Feld ist.
    In meinem Fall sind mehr als 25 Jahre vergangen, und trotzdem führen wir immer noch dieselben Diskussionen über nahezu „Grundlegendes“. Das ist nicht unbedingt schlecht, aber der Fortschritt ist langsam, und man kann es auch nicht allein bestimmten Unternehmen, Konsortien oder kommerziellen Interessen anlasten.

    • Ehrlich gesagt gibt es dasselbe Problem auch außerhalb des Engineerings. C4 ist letztlich eine Methode, ein Gespräch auf eine Abstraktionsebene zu fokussieren.
      Wie oft hat jemand in einem Gedankengang ständig zwischen hoher Detailtiefe und hoher Komplexität einerseits und aus der Ferne betrachteter Einfachheit andererseits hin- und hergewechselt, sodass schwer zu verstehen war, worauf er hinauswill? Dasselbe Problem entsteht, wenn ein Entwickler denkt: „Ich zeichne einfach ein paar Boxen und Pfeile auf dieses Board; in meinem Kopf ergibt das Sinn, also ist es ein gutes Diagramm.“
  • Auch wer kein Bauingenieur ist, kann Dinge wie Grundrisse sofort verstehen und als nützlich empfinden.
    Aber selbst als professioneller Software Engineer wirken diese Beispieldiagramme auf mich nicht nützlich oder informativ genug, um den Aufwand zu rechtfertigen. Code ist zu mehrdimensional, um ihn gut in einer zweidimensionalen Zeichnung anzunähern; das funktioniert nicht gut. Was Potenzial hat, sind stärker konventionalisierte Architektur-Code-Patterns, etwa strukturierte Nebenläufigkeit, und vielleicht etwas auf noch höherer Ebene.

    • Das liegt daran, dass Softwarearchitekturdiagramme viel Kontext brauchen oder in einem bestimmten Kontext und einem ziemlich engen Scope liegen müssen.
      Bei einem Grundriss ist der Kontext sehr festgelegt und der Scope begrenzt. Ein Fenster muss man zum Beispiel nicht erklären. In Software muss man die meisten „Fenster“ aber tatsächlich erklären. Weil alle „Fenster“ oder Elemente unterschiedlich sind, kann man nicht einfach sagen, das hier sei ein Fenster, und es 20-mal kopieren.
  • Wenn sich das C4-Modell zu willkürlich und übermäßig spezifiziert anfühlt: Ich habe Anfang des Jahres über eine alternative Praxis geschrieben: https://www.ilograph.com/blog/posts/concrete-diagramming-mod...

  • Mir gefällt dieses Modell, und ich musste auch schon UML in der Security-Architektur einsetzen. Denn dort ist Konsistenz vom obersten Kontext bis hinunter zum Code der entscheidende Punkt.
    Die Einfachheit des C4-Modells ist eine Art Zwangsmechanismus. Wenn es versteckte Kontexte oder Komponenten gibt, müssen sie im Modell sichtbar werden. Wenn es schon gegen etwas so Einfaches Widerstand gibt, sehe ich das als Hinweis darauf, dass es versteckte Elemente geben könnte. In großen Projekten gibt es solche Elemente tatsächlich meistens. Wenn man Menschen auf diese Weise dazu bringt, ihr Denken zu klären, verpflichten sie sich auf Aussagen und Ideen, statt sich nur das Recht vorzubehalten, Vorschläge zu machen und Kritik zu üben; dadurch wird Autorität verteilt. Dagegen kann es ebenfalls viel Widerstand geben. Das ist jedoch kein Problem des Modells, sondern etwas, das passiert, wenn das Modell auf Menschen trifft. Weil mir die Konsistenz gefällt, würde ich einen solchen Ansatz wohl als Referenz für Security-Design verwenden.

  • C4 ist sehr interessant und adressiert meiner Ansicht nach bestimmte Probleme der Softwarearchitektur gut.
    Es verschiebt die unteren Schichten der Architektur, also vor allem Hardware und Systemsoftware, in eine breite Abstraktion und lenkt den Aufwand auf das, was darüber im Stack liegt. Das passt erstaunlich gut zu heutigen Cloud-basierten, containerisierten und skalierbaren Ansätzen. In diesem Zusammenhang ist auch ArchiMate gut und überschneidet sich in vielen Bereichen, steht aber stärker mit einem Bein in der Infrastruktur. In der Vergangenheit habe ich mit einem ArchiMate-ähnlichen Diagrammansatz sehr gute Erfahrungen gemacht, um Konflikte zwischen Systemen und Datenquellen zu reduzieren und zu zeigen, wie die Dinge, die wir einkaufen und anbinden, bestimmte Geschäfts- und User-Workflow-Anforderungen unterstützen. Dass solche Dinge vom Codebestand abweichen, ist völlig richtig. Aber wenn man komplexe Systeme analysieren oder Systeme und Pläne einer größeren Gruppe vermitteln muss, können sie hervorragende Werkzeuge sein. Erstaunlich oft gibt es überhaupt keine zusammenhängende Dokumentation, und allein ein paar Wochen damit zu verbringen, Kästen und Verbindungslinien zu zeichnen, kann festgefahrene, frustrierende Arbeit lösen und vereinfachen. Besonders dann, wenn mehrere Teams im selben Bereich arbeiten. C4, ArchiMate, UML usw. sind letztlich nur eingeschränkte Diagrammsprachen, die bestimmte Inhalte erfassen, die man vermitteln, analysieren oder dokumentieren möchte. Als Werkzeuge für Vorabplanung oder Design halte ich sie für nicht besonders gut. Viele Leute haben unter der großen UML-Welle gelitten. Damals hieß es sinngemäß, eine Organisation aus Chefarchitekten müsse jeden Aspekt des Systems bis hin zu Klassendefinitionen schmerzhaft detailliert ausarbeiten, bevor auch nur eine Zeile Code geschrieben wird, und Wahnsinn wie „man kann den Code einfach aus den Diagrammen generieren“ hat unzählige Menschen geplagt. Sobald die eigentliche Programmierung begann, wurden diese Tausenden Stunden Planung meist ignoriert, und die Entwickler machten am Ende doch, was sie wollten.