Amortisiert durch schnellere inkrementelle Entwicklung
Code-Beispiel: Bestellsystem
OrderService.java
publicdoublecheckout(Order order){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;} Database.save(order); Email.send(order.customer.email,"Order placed!");return total;}
PaymentService.java
publicvoidvalidatePayment(Order order,double paidAmount){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;}if(total != paidAmount){thrownewIllegalStateException("Invalid payment");}}
InvoiceService.java
publicdoublegenerateInvoice(Order order){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;}return total;}
Code-Beispiel: Änderung – Black Friday
30% Rabatt, nur am Black Friday! 🤑
OrderService.java
publicdoublecheckout(Order order,boolean isBlackFriday){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;}if(isBlackFriday){ total *=0.7;} Database.save(order); Email.send(order.customer.email,"Order placed!");return total;}
PaymentService.java
publicvoidvalidatePayment(Order order,double paidAmount,boolean isBlackFriday){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;}if(isBlackFriday){ total *=0.7;}if(total != paidAmount){thrownewIllegalStateException("Invalid payment");}}
InvoiceService.java
publicdoublegenerateInvoice(Order order){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;}// BUG: Black Friday discount forgottenreturn total;}
Microservice-orientiertere Architektur
OrderService.java
publicdoublecheckout(Order order){double total =0;for(Item item : order.items){ total += item.price;}if(order.customer.isPremium()){ total *=0.9;} Database.save(order); Email.send(order.customer.email,"Order placed!");return total;}
privatefinalList<DiscountPolicy> discounts;publicdoublecalculate(Order order){double total =0;for(Item item : order.items){ total += item.price;}for(DiscountPolicy discount : discounts){ total = discount.apply(total, order);}return total;}
Beobachtungen aus dem Beispiel
Geeignete Architektur erleichtert Änderungen 👍
Ungeeignete in geeignete Architektur zu überführen ist aufwändig 👎
→ Architekturentscheidung früh im Entwicklungsprozess
→ Wie entscheidet man bevor Architekturprobleme auftreten? 🤔
Architekturmuster (“Patterns”)
Viele verbreitete Architekturen:
Microservices: Siehe Beispiel
Layers: Stufenweise Abstraktion, z.B. Netzwerkprotokoll-Stack
Pipes and Filters: Sequenzielle Datentransformation, z.B. Compiler
Model-View-Controller (MVC): Trennung von Daten/Repräsentation/Änderung, z.B. Webanwendung
…
Eignung hängt vom Anwendungsfall ab
Vorteile von Architekturmustern
Kodieren jahrzehntelange Domänenerfahrung
Verbreitete Kenntnis bei Entwicklern → De-Facto Standards
Kommunikation
Einarbeitung in bestehende Systeme
Z.T. Umsetzung in Frameworks (z.B. MVC in Rails, Django, Spring MVC)
Zusammenfassung 🏁
Was ist interne Qualität und “Cruft”?
Wie beeinflusst Cruft die Entwicklungseffizienz?
Wie beeinflusst Softwarearchitektur Cruft?
Weshalb braucht man “Architekturmuster”?
Ausblick 🔭
Ergänzungen und Anknüpfungspunkte:
Detaillierte Diskussion verbreiteter Architekturmuster mit Anwendungsbeispielen
Kursprojekt: Interaktives Daten-Dashboard mit MVC-Framework
Kritische Reflexion: Objektive Güte versus Normativität von Architektur
Übergang von Architektur zu OOD: Umsetzung von Architekturen
Literatur:
Fowler, Martin: Software Architecture Guide, available online, accessed 2025-01-06
Fowler, Martin (2003). Who needs an architect? IEEE Software, 20(5), 11–13.
Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P. and Stal, M. (1996). Pattern-Oriented Software Architecture Volume 1: A System of Patterns, Wiley & Sons
Martin, Robert C. (2017). Clean Architecture: A Craftsman’s Guide to Software Structure and Design. Prentice Hall