Software Design
Allgemeine Prinzipien und Muster zur Strukturierung von Software-Systemen, die Anforderungen in modulare, wartbare und erweiterbare Entwürfe überführen.
Klassifikation
- KomplexitätMittel
- AuswirkungTechnisch
- EntscheidungstypArchitektur
- OrganisationsreifeFortgeschritten
Technischer Kontext
Prinzipien & Ziele
Use Cases & Szenarien
Kompromisse
- Falsche Modularisierung führt zu hoher Kopplung.
- Unzureichende Dokumentation erschwert Wartung und Onboarding.
- Veraltete Entwurfsentscheidungen können technische Schulden erzeugen.
- Entscheidungen früh dokumentieren und nachverfolgen.
- Kleine, verständliche Module mit klaren Schnittstellen entwerfen.
- Automatisierte Tests und CI für Design-Validierung nutzen.
I/O & Ressourcen
- Produktanforderungen und User Stories
- Nicht-funktionale Anforderungen (z. B. Performance, Sicherheit)
- Bestehende Architektur- und Infrastrukturinformationen
- Architektur- und Design-Dokumente
- Schnittstellenspezifikationen und APIs
- Entscheidungsprotokolle und Trade-off-Analysen
Beschreibung
Software Design beschreibt Struktur, Komponenten und Interaktionen eines Systems, um funktionale und nicht-funktionale Anforderungen zu erfüllen. Es vermittelt Entscheidungen zu Modularität, Schnittstellen und Mustern und verbindet Anforderungen mit Implementierung. Gute Auslegung erhöht Wartbarkeit, Skalierbarkeit und erleichtert langfristige Evolution durch dokumentierte Entwurfsentscheidungen.
✔Vorteile
- Verbesserte Wartbarkeit durch klare Modulgrenzen.
- Erhöhte Skalierbarkeit durch geeignete Aufgabentrennung.
- Bessere Teamorganisation durch eindeutige Verantwortlichkeiten.
✖Limitationen
- Initialer Aufwand für Architekturarbeit kann hoch sein.
- Überdesign kann die Entwicklung verlangsamen.
- Nicht alle Anforderungen lassen sich sauber modularisieren.
Trade-offs
Metriken
- Zyklomatische Komplexität
Misst Komplexität einzelner Module und hilft, komplizierte Stellen zu identifizieren.
- Code-Abhängigkeiten
Anzahl und Dichte von Abhängigkeiten zwischen Modulen als Indikator für Kopplung.
- Time-to-change
Zeit, die benötigt wird, um eine Anforderungsänderung bis in Produktion zu bringen.
Beispiele & Implementierungen
Domain-Driven Design für komplexe Domänen
DDD strukturiert Modelle, Grenzen und Aggregates, um Komplexität in Fachdomänen handhabbar zu machen.
RESTful API-Design in einer Microservice-Architektur
Versionierte Ressourcen, HATEOAS-Prinzipien und klare Fehlercodes unterstützen Integrationsstabilität.
Clean Architecture zur Trennung von Domäne und Infrastruktur
Schichten und Abstraktionen isolieren Geschäftsregeln von Details, was Testbarkeit und Austauschbarkeit verbessert.
Implementierungsschritte
Anforderungs- und Kontextanalyse durchführen.
Kandidaten für Komponenten und Schnittstellen skizzieren.
Entwurfsentscheidungen mittels Trade-off-Analysen treffen und dokumentieren.
Prototypen bauen, testen und iterativ verfeinern.
⚠️ Technische Schulden & Engpässe
Tech Debt
- Veraltete Schnittstellen ohne Rückwärtskompatibilität.
- Unzureichende Modularisierung, die spätere Änderungen blockiert.
- Fehlende Tests für zentrale Integrationspunkte.
Bekannte Engpässe
Beispiele für Missbrauch
- Komplexe Architektur für triviale Anwendungen einsetzen.
- Schnittstellen häufig brechen statt kompatibel zu erweitern.
- Designentscheidungen nicht dokumentieren und implizit im Code belassen.
Typische Fallen
- Zu frühe Spezifikation ohne reale Nutzungsdaten.
- Vernachlässigung nicht-funktionaler Anforderungen bis zur Produktion.
- Widersprüchliche Ziele ohne Priorisierung (z. B. Flexibilität vs. Delivery-Speed).
Erforderliche Fähigkeiten
Drivers (Architectural Drivers)
Constraints
- • Technologie-Stack des Unternehmens
- • Budget- und Zeitvorgaben
- • Regulatorische Anforderungen an Daten und Sicherheit