llustration von vier Entwickler:innen, die gemeinsam um einen Architekturplan mit Kästen und Linien stehen und diskutieren.

Architektur ist Kommunikation: Warum gute Systeme mehr über Teams erzählen als über Technik

Wenn wir über Softwarearchitektur sprechen, denken viele zuerst an Diagramme, Patterns oder Frameworks. Wir reden über Schichtenmodelle, über SOLID oder über Ports & Adapters. All das ist wichtig, aber nicht alles. In Wahrheit ist Architektur weit mehr als Technik. Architektur ist Kommunikation jedes System erzählt eine Geschichte darüber, wie sein Team funktioniert.


Was Softwarearchitektur wirklich abbildet

Architektur ist nie neutral. Sie dokumentiert Entscheidungen darüber, was wichtig ist, welche Regeln gelten und wo Grenzen liegen. Jede Namenskonvention, jede Abkürzung sendet eine Botschaft. Systeme mit klarer Struktur bauen auf abgestimmte Kommunikation. Systeme mit unklaren Grenzen zeigen, dass im Team selbst Chancen zur Verständigung fehlen. Architektur ist damit nicht primär Technik, sondern Ausdruck von Zusammenarbeit.


Kommunikation im Code

Code ist ein Medium für Kommunikation zwischen Entwickler:innen. Jede Klasse, jede Methode und jede Schnittstelle trägt die Handschrift dessen, der sie definiert. Entscheidend ist: Kommunikation entsteht nicht durch lange Kommentare, sondern durch klare Benennung, nachvollziehbare Struktur und eindeutige Abgrenzungen.

Ein gut gewählter Methodenname erklärt sich selbst besser als jeder Absatz im Kommentar. Ein konsistentes Moduldesign sagt mehr über Intention und Funktionalität aus als ein erklärender Textblock daneben. Kommentare sind sinnvoll für komplexe Entscheidungen oder Ausnahmen sie ersetzen aber keine verständliche Struktur.

Worst Case: Kommentare erklären Chaos

Im folgenden Beispiel versucht der Code, mangelnde Struktur durch Kommentare zu kompensieren. Logik, Datenzugriff und E-Mail-Versand sind vermischt, Verantwortlichkeiten unklar, Sicherheitslücken vorprogrammiert:

<?php
class OrderController
{
    public function create()
    {
        // get data from POST
        $d = $_POST;

        // validate (very basic) - TODO: make better
        if (!isset($d['email']) || strpos($d['email'], '@') === false) {
            echo "bad email";
            return;
        }

        // connect to db
        $pdo = new PDO('mysql:host=localhost;dbname=shop', 'root', 'root');

        // check stock (1 means in stock… usually)
        $stmt = $pdo->query("SELECT stock FROM items WHERE id=".(int)$d['item_id']);
        $row = $stmt->fetch();
        if (!$row || $row['stock'] < ($d['qty'] ?? 1)) {
            echo "no stock";
            return;
        }

        // insert order (no transaction for now)
        $pdo->exec("INSERT INTO orders (email, item_id, qty, total) VALUES ('".$d['email']."', ".(int)$d['item_id'].", ".(int)$d['qty'].", ".((int)$d['qty']*999).")");

        // reduce stock (hope this is fine)
        $pdo->exec("UPDATE items SET stock = stock - ".(int)$d['qty']." WHERE id=".(int)$d['item_id']);

        // send email (simple)
        mail($d['email'], "Your order", "Thanks for your order!");
    }
}

Was kommuniziert dieser Code?
Unscharfe Verantwortung, implizite Annahmen, Sicherheitsrisiken und „Kommentare als Pflaster“.

Best Case: Struktur erklärt sich selbst

Im besseren Beispiel sprechen Klassen- und Methodennamen für sich. Domänenlogik, Persistenz und E-Mail sind sauber getrennt, Fehlerfälle klar benannt, Tests einfach möglich:

<?php
declare(strict_types=1);

namespace App\Order;

final class PlaceOrderService
{
    public function __construct(
        private OrderRepository $orders,
        private Inventory       $inventory,
        private PriceCalculator $prices,
        private Mailer          $mailer,
        private UnitOfWork      $uow,
    ) {}

    public function place(PlaceOrderRequest $req): OrderId
    {
        $email = EmailAddress::from($req->email);

        if (!$this->inventory->hasAvailable($req->itemId, $req->quantity)) {
            throw new InsufficientStock("Item not available.");
        }

        $total = $this->prices->forItem($req->itemId, $req->quantity);

        return $this->uow->transaction(function () use ($req, $email, $total) {
            $orderId = $this->orders->create($email, $req->itemId, $req->quantity, $total);
            $this->inventory->reserve($req->itemId, $req->quantity);
            $this->mailer->sendOrderConfirmation($email, $orderId, $total);

            return $orderId;
        });
    }
}

final class PlaceOrderRequest
{
    public function __construct(
        public readonly string $email,
        public readonly ItemId $itemId,
        public readonly int    $quantity,
    ) {}
}

final class EmailAddress
{
    private function __construct(private string $value) {}

    public static function from(string $raw): self
    {
        $normalized = mb_strtolower(trim($raw));
        if (!filter_var($normalized, FILTER_VALIDATE_EMAIL)) {
            throw new \InvalidArgumentException("Invalid email: {$raw}");
        }
        return new self($normalized);
    }

    public function toString(): string { return $this->value; }
}

Was kommuniziert dieser Code?

  • Intent: PlaceOrderService::place() erzählt die Geschichte „Bestellung annehmen“.
  • Verantwortung: Preisberechnung, Lager, Persistenz und E-Mail klar getrennt.
  • Fehlerdomäne: Sprechende Exceptions statt Magic Returns.
  • Verträge: Interfaces definieren Erwartungen, Tests sind leicht zu schreiben.
  • Kommentare: Nur dort, wo sie echten Mehrwert haben – nicht als Ersatz für gute Namen.

Warum schlechte Architektur Kommunikationsprobleme sichtbar macht

Schlechte Architektur entsteht selten aus Willkür, vielmehr durch Missverständnisse: unklare Anforderungen, fehlende Abstimmungen oder implizite Annahmen. Diese spiegeln sich im Code wider: widersprüchliche Namenskonventionen, doppelte Logik oder fehlende klare Verantwortlichkeiten. Code enthält mehr als technische Logik – er enthält Teamdynamik.


Architektur als Spiegel der Organisation

Das sogenannte Conway’s Law stellt klar: Architektur spiegelt die Kommunikationsstruktur der Organisation wider. Das heißt: isolierte Teams → isolierte Systeme; integrative Teams → modulare, durchdachte Architektur. Architektur wird so zur ungeschönten Reflektion der Organisationskultur.


Haltung: Architektur als bewusste Kommunikation

Gute Architektur leben heißt nicht, sie perfekt zu gestalten. Sondern sie sichtbar, nachvollziehbar und verständlich zu machen. Begriffe gehören abgestimmt, Entscheidungen transparent, Strukturen erklärt.

Architektur als Kommunikation heißt Verantwortung sowohl für das Team, das sie entwirft, als auch für jene, die später damit arbeiten. Systeme, die auf Verständlichkeit bauen, gewinnen Vertrauen. Systeme, die nur von Einzelnen verstanden werden, verlieren es.


Grundlagen solider Architektur: SOLID-Prinzipien

SOLID steht für fünf zentrale Prinzipien objektorientierten Designs: Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion. Sie liefern technische Regeln mit kommunikativer Kraft:

  • Single Responsibility Principle: Jede Klasse hat eine einzige Aufgabe.
  • Open-Closed Principle: Systeme sollen erweiterbar, aber nicht modifizierbar sein.
  • Die weiteren Prinzipien stellen klare Abstraktion, saubere Schnittstellen und geringe Abhängigkeiten sicher.

SOLID ist nichts anderes als angewandte Klarheit in Code und in Kommunikation.


Fazit

Architektur ist Kommunikation. Sie erzählt von Teams, Organisationen und deren Haltung. Gute Software entsteht dort, wo klare, bewusste Absprachen herrschen. Schlechte Systeme entstehen dort, wo Kommunikation fehlt.

Wer bessere Software anstrebt, sollte zuerst die Kommunikation optimieren. Denn:

Jede Architektur ist ein Gespräch – in Code gegossen.

Leave a Reply