24,99 €
Tragfähige Literatur für Ihre Softwarearchitekturen
Besuchen Sie eine Veranstaltung zu Softwarearchitektur oder stehen Sie in einem Projekt vor Architekturentscheidungen und wollen daher die aktuellen Architekturansätze verstehen? Dann hilft Ihnen dieses Buch. Holger Gast erläutert zunächst die grundlegenden Elemente von Architekturen und führt die technischen Hintergründe aus. Er erklärt Ihnen danach die klassischen Stile und Patterns und geht schließlich auf Cloud-Architekturen ein. Durchgängig legt er den Fokus auf konkrete Softwarestrukturen statt auf Theorie und ermöglicht Ihnen so einen verständlichen und zügigen Einstieg in das Thema.
Sie erfahren
Sie lesen das E-Book in den Legimi-Apps auf:
Seitenzahl: 734
Veröffentlichungsjahr: 2023
Softwarearchitektur für Dummies
Layers
Löst eine umfangreiche Aufgabe, indem es Schritt für Schritt immer leistungsfähigere Abstraktionen aufeinanderschichtet und damit immer mehr Details der Lösung verbirgt. Weil die Detailschichten unabhängig von den höheren sind, können sie möglicherweise wiederverwendet werden.
Pipes and Filters
Zerlegt eine Aufgabe in einzelne Transformationsschritte auf Datenströmen und gewinnt damit Flexibilität, Erweiterbarkeit und Wiederverwendbarkeit.
Model-View-Controller
Entkoppelt in interaktiven Anwendungen die Benutzerschnittstelle vom Kern aus Business-Logik und der Datenhaltung. So hält es die Benutzerschnittstelle flexibel und gleichzeitig den Kern stabil.
Model-View-ViewModel
Entkoppelt in interaktiven Anwendungen die technische Benutzerinteraktion von der Aufbereitung der Daten für die Anzeige und der inhaltlichen Reaktion auf Benutzereingaben. So wird diese Logik testbarer und weniger fehleranfällig.
Command-Processor
Realisiert Undo/Redo-Funktionalität für interaktive Anwendungen.
Interceptor
Macht eine Anwendung erweiterbar, indem es an vordefinierten Stellen in der Anwendungslogik Callbacks von Plugins aufruft, sodass sie eigene Funktionalität beitragen können.
Microkernel
Beschreibt eine erweiterbare Anwendung als Sammlung von Plugins, die miteinander interagieren können.
Reactor
Ermöglicht extrem effiziente, eventgetriebene I/O und bildet damit eine wesentliche Grundlage für das C10M-Problem.
Proactor
Ermöglicht extrem effiziente, asynchrone I/O, die von der Anwendung anstatt durch Events getrieben wird.
Enterprise Integration Patterns
Eine Sammlung vieler Patterns, die zusammen eine zuverlässige Integration verschiedener Anwendungen auf der Basis von Messaging ermöglichen.
Microservices
Verteilt die Anwendungslogik nach inhaltlich getrennten Bereichen auf einzelne Services, die jeweils die vollständige Funktionalität, inklusive einer eigenen Datenbank, enthalten. Daraus folgt eine starke Entkopplung, bis hin zu unterschiedlichen Technologie-Stacks, sowie eine unabhängige Skalierbarkeit einzelner Funktionsbereiche.
Hexagonale Architekturen
Lösen die Asymmetrie des Layers-Patterns zwischen höheren und niedrigeren Aufgaben auf durch den Fokus auf die Trennung von innen und außen einer Komponente. Das erlaubt flexiblere Definitionen der Schnittstellen zu anderen Komponenten.
Three-Tier Architecture
Teilt bei Web-Anwendungen die Anwendungslogik in die drei Bereiche Benutzerschnittstelle, Business-Logik und Datenhaltung und bietet Strategien für die entsprechenden Design-Entscheidungen.
Message-Driven
Ermöglicht eine stark entkoppelte Kommunikation zwischen Komponenten und Anwendungen auf Basis einer Messaging-Infrastruktur.
Event-Driven
Formuliert die Anwendungslogik durchgehend als Reaktion auf auftretende Events. Eine Reaktion kann selbst wieder Events erzeugen und damit weitere Reaktionen anstoßen. Weil die Reaktionen unabhängig davon sind, was die Events ausgelöst hat, sind die Anwendungsteile stark entkoppelt.
Reactivity
Geht von der Forderung einer durchgehenden Verfügbarkeit und niedrigen Antwortzeiten einer Anwendung aus und bietet Frameworks, um diese durch asynchrone, eventgetriebene und resiliente Anwendungslogik zu erreichen.
Space-Based Architecture
Erlaubt hochskalierbare Anwendungen durch die Verteilung der Anwendungslogik auf horizontal skalierbare Processing Units, die den Datenbestand lokal in In-memory Data-Grids cachen und diese Caches synchronisieren.
Softwarearchitektur für Dummies
Bibliografische Informationder Deutschen Nationalbibliothek
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.d-nb.de abrufbar.
1. Auflage 2024© 2024 Wiley-VCH GmbH, Boschstraße 12, 69469 Weinheim, Germany
All rights reserved including the right of reproduction in whole or in part in any form. This book published by arrangement with John Wiley and Sons, Inc.
Alle Rechte vorbehalten inklusive des Rechtes auf Reproduktion im Ganzen oder in Teilen und in jeglicher Form. Dieses Buch wird mit Genehmigung von John Wiley and Sons, Inc. publiziert.
Wiley, the Wiley logo, Für Dummies, the Dummies Man logo, and related trademarks and trade dress are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its affiliates, in the United States and other countries. Used by permission.
Wiley, die Bezeichnung »Für Dummies«, das Dummies-Mann-Logo und darauf bezogene Gestaltungen sind Marken oder eingetragene Marken von John Wiley & Sons, Inc., USA, Deutschland und in anderen Ländern.
Das vorliegende Werk wurde sorgfältig erarbeitet. Dennoch übernehmen Autoren und Verlag für die Richtigkeit von Angaben, Hinweisen und Ratschlägen sowie eventuelle Druckfehler keine Haftung.
Coverfoto: Tierney – stock.adobe.comKorrektur: Isolde Kommer
Print ISBN: 978-3-527-72001-9ePub ISBN: 978-3-527-83979-7
Holger Gast studierte in Tübingen Informatik, promovierte zu Programmiersprachen und habilitierte sich mit einer Arbeit zur Software-Korrektheit. In seiner Forschung beschäftigt er sich unter anderem mit der Didaktik der Informatik. Seit 2005 hält er Vorlesungen und Seminare zu Software-Architektur und Software-Design, objektorientierter Programmierung und verwandten Themen.
Seit 2014 leitet er das Steinbeis-Beratungszentrum Agile Entwicklung von Informationssystemen. Hier begleitet er die Erstellung von Individual-Software für Unternehmen von den ersten Planungen über die Architektur bis zur Realisierung.
Cover
Titelblatt
Impressum
Über den Autor
Inhaltsverzeichnis
Einleitung
Über dieses Buch
Konventionen in diesem Buch
Was Sie nicht lesen müssen
Törichte Annahmen über die Leser
Wie dieses Buch aufgebaut ist
Symbole, die in diesem Buch verwendet werden
Wie es weitergeht
Notiz
Teil I: Überblick
Kapitel 1: Wie wir Software-Systeme bauen
Aufgaben und Ziele von Architektur
Die Rolle des Architekten
Wo Sie mehr lesen können
Kapitel 2: Das Mindset des Architekten
Software im Unternehmen
Hinterfragen für Fortschritt
Umgang mit Technologie
Es menschelt
Teil II: Elemente von Architekturen
Kapitel 3: Das hab ich extra vergessen – Abstraktion
Warum wir abstrahieren
Wie wir abstrahieren
Kapitel 4: Wenn Rechner gesprächig werden – Netzwerke
Anforderungen an Netzwerke
Aufbau und Leistung von Netzwerken
Näher hingeschaut: TCP/IP
Ein eigenes kleines Netz
Folgerungen für die Software-Architektur
Wo Sie mehr lesen können
Kapitel 5: Zu viel zu tun für einen allein – Nebenläufigkeit
Technische Grundlagen
Synchronisation zwischen Threads
Thread-Organisation
Wo Sie mehr lesen können
Kapitel 6: Vom Notizblock bis zum Aktenschrank – Datenhaltung
Die Rolle von Daten im Software-Projekt
Die Grundlage von allem – das Dateisystem
Klassische Lösungen für klassische Probleme – relationale Datenbanken
Folgerungen für die Architektur
Wo Sie mehr lesen können
Teil III: Klassische Patterns und Stile
Kapitel 7: Wer macht was – Grundlegende Modularisierungsansätze
Mehr als ein Buzzword: Decoupling
Decoupling mit Design-by-Contract
Schichten/Layers
Wo Sie mehr lesen können
Kapitel 8: Ich hätt' noch eine kleine Bitte – Erweiterbarkeit
Erweiterbarkeit auf der Design-Ebene
Frameworks
Das Interceptor-Pattern
Das Microkernel-Pattern/Plugin-Architekturen
Folgerungen für die Architektur
Wo Sie mehr lesen können
Kapitel 9: Rechnen auf dem Schreibtisch – Aufbau lokaler Anwendungen
Herausforderungen von Benutzerschnittstellen
Das Model-View-Controller-Pattern
Das Wichtigste liegt innen – das Model
Ups, das wollte ich nicht – Undo/Redo
Schichten beim MVC
Das Model-View-ViewModel-Pattern
Wo Sie mehr lesen können
Kapitel 10: Steckdosen und Verbindungen – Netzwerkanwendungen
Programmieren mit Netzwerken
Ein typischer Server-Aufbau
Die 8 Fallstricke bei verteilten Systemen
Das Problem der zwei Generäle
Three-Tier-Architekturen
Wo Sie mehr lesen können
Kapitel 11: Alle Hände voll zu tun – wenn viele Dinge gleichzeitig passieren
Eventgetriebene I/O
Asynchrone I/O
Komplexität durch Event-driven Architecture
Wo Sie mehr lesen können
Kapitel 12: Der neue Ölboom – Analysen auf Daten
Pipes and Filters
Business-Intelligence-Lösungen
Archive für die Datenanalyse – Data-Warehouses
Wo Sie mehr lesen können
Anmerkungen
Teil IV: Architekturen für die Cloud
Kapitel 13: Das erledige ich schnell für Sie – Services
Aus einem Stein gemeißelt – der Monolith
Microservices
Hexagonale Architekturen
API-Design für Services
Serverless Architectures
Stile der Zusammenarbeit
Eventual Consistency mit Sagas
Wo Sie mehr lesen können
Kapitel 14: Hab ich dir doch gesagt – Messages
Ich vertraue Ihnen diesen Brief an – Message Brokers
Grundlegende Muster für Nachrichten
Asynchrone Service-Kommunikation mit Messages
Wo Sie mehr lesen können
Kapitel 15: Zusammenwachsen – Enterprise-Integration-Patterns
Anwendungen verbinden
Abstraktion über den Empfänger
Prozesse organisieren
Wo Sie mehr lesen können
Anmerkungen
Kapitel 16: Auf den Punkt fit – Reactivity
Reactivity als Konzept
Reactive Streams
Folgerungen für die Architektur
Wo Sie mehr lesen können
Kapitel 17: Das weiß ich schon längst – Verteilte Datenhaltung
Die Herausforderung
Schwächere Zusicherungen
Konflikterkennung und -behandlung
Folgerungen für die Architektur
Es muss nicht immer SQL sein – NoSQL-Datenbanken
Space-based Architecture
Wo Sie mehr lesen können
Teil V: Top-Ten
Kapitel 18: Zehn Meilensteine des Software-Engineerings
Hochsprachen
Funktionale Programmierung
Softwaretechnik-Sprachen
Objektorientierte Sprachen
Garbage Collection
Typsysteme
IDEs
Agile Software-Entwicklung
Free Software und Open-Source-Software
Cloud-Computing
Kapitel 19: Zehn einflussreiche Ideen
Software-Engineering
No Silver Bullet
Coupling und Cohesion
Separation of Concerns
Information Hiding
Responsibility-driven Design
Verträge
Behavioural Subtyping
Inversion of Control
Refactoring
Kapitel 20: Zehn Hypes
Objektorientierte Programmierung
Komponenten
Middleware
Model-driven Development und Architecture
DevOps
Reactivity
Serviceorientierte Architekturen
Microservices
Ökosysteme in der Cloud
Low-Code-Plattformen
Literaturverzeichnis
Abbildungsverzeichnis
Stichwortverzeichnis
End User License Agreement
Kapitel 4
Abbildung 4.1: Leistungen von Netzwerken
Abbildung 4.2: Pakete und Abstraktionen in Netzwerken
Abbildung 4.3: Multiplexing in Netzwerken
Abbildung 4.4: Abstraktion Datenflüsse
Abbildung 4.5: Grundsätzliches Modell Link Layer
Abbildung 4.6: Details zu Schicht 1
Abbildung 4.7: Überblick Routing
Abbildung 4.8: Hierarchisches Routing
Abbildung 4.9: Subnetz-Adressierung
Abbildung 4.10: TCP-Verbindungsmodell
Abbildung 4.11: TCP-Header
Abbildung 4.12: Ringpuffer
Abbildung 4.13: Ringpuffer des Senders in der TCP-Verbindung
Abbildung 4.14: Ringpuffer auf Empfänger-Seite
Kapitel 5
Abbildung 5.1: Technischer Überblick Parallelität
Abbildung 5.2: Die Wirkung von Memory-Barriers
Abbildung 5.3: Verwaltung des virtuellen Speichers
Abbildung 5.4: Race-Condition
Abbildung 5.5: Deadlocks
Abbildung 5.6: Condition Variables
Abbildung 5.7: Blocking-Queues
Abbildung 5.8: Leader-Followers-Pattern
Kapitel 6
Abbildung 6.1: Datenbanken als Ablageort für Informationen
Abbildung 6.2: Zugriff auf gespeicherte Daten
Abbildung 6.3: Überblick Dateisystem
Abbildung 6.4: Konsistenz und Transaktionen
Abbildung 6.5: Das Datenbank-Log
Abbildung 6.6: Two-Phase-Commit-Protokoll
Kapitel 7
Abbildung 7.1: Coupling
Abbildung 7.2: Cohesion
Abbildung 7.3: Methodenaufruf mit Design-by-Contract
Abbildung 7.4: Grundstruktur Layers
Abbildung 7.5: Layers mit Blocking-Nachrichten
Kapitel 8
Abbildung 8.1: Herausforderung Erweiterbarkeit
Abbildung 8.2: Cohesion als Schlüssel für Erweiterungen
Abbildung 8.3: Das Strategy-Pattern
Abbildung 8.4: Grundstruktur Frameworks
Abbildung 8.5: Das Interceptor-Pattern
Abbildung 8.6: Struktur Microkernel-Pattern
Kapitel 9
Abbildung 9.1: Grundstruktur des Model-View-Controller Patterns
Abbildung 9.2: Observer-Pattern beim MVC
Abbildung 9.3: Die Document-View-Variante des MVC
Abbildung 9.4: Aufgaben des Models
Abbildung 9.5: Screenshots Zeichenprogramm
Abbildung 9.6: Undo/Redo mit dem Command-Pattern im MVC
Abbildung 9.7: Der Command Processor
Abbildung 9.8: MVC: Reaktion auf Eingaben und Model-View-Separation
Abbildung 9.9: Aufteilung von Logik in »view-level« und »model-level« im MVC
Abbildung 9.10: Das Model-View-ViewModel-Pattern
Kapitel 10
Abbildung 10.1: Socket-API zum Verbindungsaufbau
Abbildung 10.2: Typischer Server-Aufbau
Abbildung 10.3: Verarbeitung von Anfragen im Server
Abbildung 10.4: Das Problem der zwei Generäle
Abbildung 10.5: Three-Tier-Architekturen
Abbildung 10.6: Innere Struktur Presentation Tier
Kapitel 11
Abbildung 11.1: Der Select-Mechanismus
Abbildung 11.2: Das Reactor-Pattern
Abbildung 11.3: Grundaufbau asynchrone I/O
Abbildung 11.4: Struktur Proactor-Pattern
Abbildung 11.5: Zustände des Client-Handlers
Kapitel 12
Abbildung 12.1: Struktur Pipes-and-Filters-Pattern
Abbildung 12.2: Verarbeitung von Datenströmen
Abbildung 12.3: Schemata für analytische Datenbanken
Abbildung 12.4: Verbindung von Fakten über geteilte Dimensionen
Abbildung 12.5: Spaltenorientierte Speicherung
Abbildung 12.6: Idee Data-Cube am Beispiel von Verkaufszahlen
Kapitel 13
Abbildung 13.1: Erweiterungen um neue Funktionen
Abbildung 13.2: Skalierungsachsen bei Microservices
Abbildung 13.3: Hexagonale Architekturen
Abbildung 13.4: Technische Grundlage für idempotente APIs
Abbildung 13.5: Struktur Remote Procedure Call
Abbildung 13.6: REST APIs für Services
Abbildung 13.7: Ausschnitt Datenmodell Bestellung
Abbildung 13.8: Webhooks bei Cloud-Services
Abbildung 13.9: Event-Sourcing
Abbildung 13.10: Grundansatz Sagas
Abbildung 13.11: Muster für Compensating Transactions: Salden und Buchungen
Kapitel 14
Abbildung 14.1: Point-to-Point-Nachrichtenübermittlung
Abbildung 14.2: Publisher/Subscriber-Kommunikation mit Topics
Abbildung 14.3: Herausforderungen für Zustellgarantien
Abbildung 14.4: Grundsätzliche Topologien für Channel-Designs
Abbildung 14.5: Herausforderung Request/Reply
Abbildung 14.6: Asynchrone Service-Kommunikation
Abbildung 14.7: Eventual Consistency durch Messages
Kapitel 15
Abbildung 15.1: Anbindung einer Anwendung an die Messaging-Infrastruktur
Abbildung 15.2: Service Activator
Abbildung 15.3: Message Translator
Abbildung 15.4: Canonical Data Model
Abbildung 15.5: Transactional Client
Abbildung 15.6: Message Router
Abbildung 15.7: Message Broker
Abbildung 15.8: Message Bus
Abbildung 15.9: Pipes and Filters für Integrationsaufgaben
Abbildung 15.10: Process-Manager-Pattern
Kapitel 16
Abbildung 16.1: Ziele und Aspekte von Reactivity (aus [16])
Abbildung 16.2: Datenströme für Reactivity
Abbildung 16.3: Zusammenarbeit zwischen Publisher und Subscriber
Abbildung 16.4: Screenshot zu UI-Events als Reactive Streams
Abbildung 16.5: Klassische Operatoren für Reactive Streams
Abbildung 16.6: Allgemeine Formen für Gesamtergebnisse
Abbildung 16.7: Der Operator flatMap
Abbildung 16.8: mehrere Subscriber für einen Stream
Abbildung 16.9: Der GroupBy-Operator
Abbildung 16.10: Grundstruktur Switch-Operatoren
Abbildung 16.11: Parallelisierung von Aufgaben
Abbildung 16.12: Test-Setup mit Reactive Streams
Kapitel 17
Abbildung 17.1: Gesamtstruktur verteilte Datenhaltung
Abbildung 17.2: Sharding mit Partition-Keys
a
und
b
Abbildung 17.3: Nebenläufige Zugriffe
Abbildung 17.4: Master/Slave-Replication
Abbildung 17.5: Die Quorum-Strategie
Abbildung 17.6: Konzept der CRDTs
Abbildung 17.7: Beispiel-Dokument Bestellung
Abbildung 17.8: Grundidee Space-based Architecture-Pattern
Abbildung 17.9: Data Pumps
Cover
Titelblatt
Impressum
Über den Autor
Inhaltsverzeichnis
Einleitung
Fangen Sie an zu lesen
Literaturverzeichnis
Abbildungsverzeichnis
Stichwortverzeichnis
End User License Agreement
1
2
5
6
7
23
24
25
26
27
29
30
31
32
33
34
35
36
37
38
39
41
42
43
44
45
46
47
48
49
50
51
53
54
55
56
57
58
59
60
61
62
63
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
425
426
427
428
429
430
431
432
433
435
436
437
438
439
440
441
442
443
445
446
447
448
449
450
451
452
453
454
Eine Anwendung ohne eine durchdachte Software-Architektur zu entwickeln, ist keine gute Idee. Wenn man ein Gebäude für einen bestimmten Zweck haben will, sagen wir, eine neue Schule, dann geht man ja auch zu einen Architekten, der schon Schulen realisiert hat. Er weiß, wie Schulen genutzt werden und woran man deshalb gleich zu Beginn denken muss, damit am Ende Schüler und Lehrer gern dort sind und mit Freude und Erfolg gelernt wird. Man würde nicht zum lokalen Bauunternehmer gehen, der zufällig die Schule in der Nachbarstadt gebaut hat und sagen: »Du kannst doch Schulen, bau uns auch eine.«
Der Software-Architekt oder die Software-Architektin1 hat eine genauso spannende Aufgabe wie der Schul-Architekt: Er muss ein guter Techniker sein, damit seine Planungen effektiv implementiert werden können. Er muss für möglichst viele Aufgaben, Probleme und Herausforderungen passende Strategien und Software-Strukturen parat haben. Er muss für das einzelne Projekt strategisch und oft kreativ eine Auswahl treffen und einen Gesamtplan entwickeln. Und schließlich muss er auch noch ausführlich mit den beteiligten Menschen sprechen und ihnen genau zuhören: mit Benutzern, Entwicklern, Projektleitern, Teamleitern, Budgetverantwortlichen und vielen weiteren – denn sie alle haben Erwartungen und Ziele, die in Architektur, Design und Implementierung einfließen.
Klingt ein bisschen kompliziert? Kein Problem, denn Sie haben das richtige Buch in der Hand. Die Rückmeldungen von Studierenden in meinen Vorlesungen und Seminaren haben mich motiviert, immer sehr konkret, mit der Implementierung im Blick, vorzugehen. Vor allem ist es mir wichtig, Technik, Patterns und Strategien nebeneinander zu stellen und ihre Querbeziehungen aufzuzeigen. Denn dann wird es richtig spannend, weil man Alternativen abwägen und Entscheidungen treffen kann, um zu guten Designs und tragfähigen Architekturen zu kommen. Und aus meinen eigenen Software-Projekten in vielen verschiedenen Anwendungsbereichen bin ich sicher: Nichts davon ist »Theorie«, alles wird früher oder später in Ihre eigenen Architekturen einfließen.
Software-Architektur versteht man erfahrungsgemäß am besten anhand von konkreten Aufgabenstellungen und den passenden Lösungen. Deshalb enthält dieses Buch:
Software-Patterns für häufig auftauchende Aufgaben und Herausforderungen
Ziele, Argumente und Strategien zur Auswahl von Patterns und zur Entscheidung zwischen alternativen Lösungen
technische Hintergründe zu Architekturen und Entscheidungen
Sie brauchen das Buch nicht von vorn nach hinten durchzulesen. Jedes Kapitel behandelt diese Punkte abgeschlossen für einen bestimmten Aufgabenbereich. Je mehr Kapitel Sie lesen, desto mehr gewinnen Sie einen Rundumblick und desto mehr Werkzeuge haben Sie zur Verfügung. Aber Sie können natürlich dort beginnen, wo im aktuellen Projekt Fragen auftauchen, oder einfach bei dem Ansatz, der Sie gerade am meisten interessiert.
Englische Fachbegriffe habe ich beibehalten, wenn es nicht gerade sehr gängige deutsche Entsprechungen gibt. Allerdings habe ich die Rechtschreibung angepasst, um das Lesen zu erleichtern: Nomen sind groß geschrieben und zusammengesetzte Begriffe stehen wie im Deutschen mit Bindestrich statt wie im Englischen in getrennten Wörtern. Beim ersten Auftreten ist ein Fachbegriff kursiv gesetzt, später nicht mehr.
Die meisten Konzepte lassen sich gut mit Beschreibungen und Illustrationen erläutern. Dort, wo es um technische Details geht und Quelltext notwendig wird, ist er in Typewriter-Font gesetzt.
Mit Ausnahme von Implementierungsbeispielen habe ich darauf verzichtet, einzelne Produkte oder Frameworks vorzustellen, weil das leicht wie eine Empfehlung oder Standardlösung wirkt und außerdem schnell veraltet. Die Produktauswahl ist ein wichtiger Teil der Architektur und speziell für jedes Projekt. Mit den Konzepten und Begriffen aus dem Text finden Sie aber leicht immer mehrere Kandidaten und können dann die besprochenen Auswahlkriterien anwenden. Die im Umfang größte Ausnahme hiervon ist Java: Die Plattform und das Ökosystem bieten viele kleine Beispiele unter einem Dach, und weil Sie wahrscheinlich Java schon begegnet sind, finden Sie sich leicht zurecht. Alle gezeigten Mechanismen gibt es analog aber auch in vielen anderen Plattformen.
Die Kapitel sind so geschrieben, dass Sie sie unabhängig voneinander lesen können. Weitgehend können Sie auch bei einzelnen Abschnitten innerhalb des Kapitels einsteigen, wenn Ihnen eine Überschrift mit einem interessanten Begriff ins Auge springt. Allerdings enthält der Text keine Rückwärtsverweise. Damit Sie wissen, was Sie verpasst haben, sollten Sie wenigstens die vorherigen Überschriften im Kapitel kurz überfliegen. Die Stichworte »weiter oben« und »weiter unten« beziehen sich immer auf Abschnitte innerhalb desselben Kapitels. Wenn es zu einem Thema ausführlichere Erklärungen anderswo im Buch gibt, verweise ich auf das jeweilige Kapitel.
Außerdem habe ich zwei Formen von »Abkürzungen zum Ziel« eingebaut, wo die Vorstellung von Patterns oder Argumenten einmal ausführlicher sein muss, damit sie verständlich wird.
Ein separater Abschnitt »Folgerungen für die Architektur« fasst rückblickend über mehrere Abschnitte zusammen, welche Punkte relevant sind, wenn Sie sich fragen, ob der vorgestellte Ansatz für Ihr Projekt sinnvoll sein kann.
Am Ende eines längeren Abschnitts mit eher detaillierten Inhalten fasst ein »Bindfaden«-Symbol, das weiter unten noch gezeigt wird, die Haupteinsicht zusammen.
Weil Sie gerade ein Buch über Software-Architektur anschauen, nehme ich einmal an, dass Sie auf irgendeine Weise mit der Entwicklung von Anwendungen zu tun haben, sei es als Entwickler, Designer, Projektleiter oder Architekt. Wahrscheinlich interessiert Sie mindestens einer der folgenden Punkte:
Sie wollen Entscheidungen zum Aufbau einer Anwendung treffen.
Sie wollen verstehen, ob eine bestimmte Architektur oder bestimmtes Framework für Ihr Projekt geeignet ist.
Sie wollen Hypes und Marketing-Erzählungen rund um Software-Architekturen endlich durchschauen.
Sie wollen als Entwickler so designen und implementieren, dass Sie bestimmte langfristige Ziele erreichen.
Sie wollen als Entwickler eine vorgegebene Architektur verstehen, um sie richtig umzusetzen.
Sie interessieren sich allgemein dafür, welche Herausforderungen man bei der Erstellung oder Weiterentwicklung einer Anwendung lösen muss.
An vielen Stellen versteht man Architektur, vor allem die Entscheidungen, nur, wenn man die Implementierung kurz durchdenkt. Und das tut der Text dann auch. Deshalb nehme ich auch an, dass Sie schon ein wenig Programmiererfahrung mitbringen. Praktische Anwendungen müssen es nicht sein, Praktika oder Übungen in fortgeschrittenen Vorlesungen an der Hochschule oder Universität reichen sicher aus.
Dieses Buch gliedert sich in fünf Teile, die allerdings nicht aufeinander aufbauen, sondern jeweils eigenständige Aspekte von Software-Architektur behandeln.
Zuerst geht es um einen kurzen Überblick über die Aufgaben von Software-Architektur und die Rolle des Software-Architekten. Die nicht-technischen Überlegungen hinter Architektur-Entscheidungen in Kapitel 2 führen in Seminaren immer zu den spannendsten Diskussionen: Wie entscheiden wir uns zwischen alternativen Lösungen, wenn keine eindeutig besser geeignet ist?
Der zweite Teil bringt Inhalte, die grundlegend für die später vorgestellten Software-Architekturen sind, aber eigentlich nicht zur Software-Architektur selbst gehören. Sie kommen deshalb normalerweise in separaten Vorlesungen oder Büchern vor. Damit Sie sich das sparen können, habe ich die relevanten Aspekte hier kurz zusammengefasst.
Einigen Raum nehmen technische Grundlagen ein, die bei vielen Architektur-Überlegungen unverzichtbar sind. Hier folge ich der Idee der Mechanical Sympathy, die ursprünglich von einem Rennfahrer formuliert wurde: Man fährt besser Auto, wenn man genau weiß, warum das Auto wie reagiert.
Der dritte Teil stellt klassische Software-Patterns für klassische Aufgabenstellungen vor. Eigentlich ein Muss für jeden Software-Architekten. Ein besonderer Fokus liegt auf der Motivation und Erläuterung der Herausforderungen und auf der Abwägung zwischen alternativen Lösungsmöglichkeiten.
Die Cloud bietet, vor allem durch die Virtualisierung von Servern, ganz neue Möglichkeiten für die Verteilung von Anwendungen auf verschiedene physische Rechner. Verteilte Systeme werden quasi zum Normalfall. Entsprechend brauchen Anwendungen aber auch Strukturen und Mechanismen, um zuverlässig mit den Unwägbarkeiten von verteilten Anwendungen umzugehen. Dazu gibt es verschiedene Architektur-Ansätze.
Die Informatik und die Software-Technik sind sehr schnelllebige Gebiete. Das birgt die Gefahr, dass sich Geschichte wiederholt: im Guten, wenn dieselben Aufgaben mehrmals und vielleicht immer besser gelöst werden. Aber auch im Schlechten, wenn dieselben Sackgassen immer wieder ausgelotet werden, in der Hoffnung, mit neuen Technologien endlich eine Lösung zu finden. Deshalb ist es auch für uns Software-Ingenieure wichtig zu wissen, wo wir herkommen: Was sind die grundlegenden Ideen und Meilensteine? Was war letztlich ein Hype, aber können wir daraus lernen?
Einige Absätze sind aus dem Textfluss hervorgehoben, damit sie gleich ins Auge springen.
Hinter dem Bindfaden-Symbol stehen Dinge, die Sie sich merken sollten. Das können Details sein, aber auch zusammenfassende Einsichten, die als Take-Home-Message noch mal eigenständig formuliert sind.
Hier stehen Hinweise, die das Verständnis erleichtern oder Querbeziehungen zu anderen Inhalten zeigen.
Das Warnschild zeigt Fallen an, in die man gedanklich leicht tappt, wenn man einen bestimmten Aspekt übersieht. Oft betrifft das scheinbare Abkürzungen, von denen man erst hinterher sieht, dass es eigentlich Sackgassen sind.
Hier geht es um technische Details, die für das konzeptuelle Verständnis nicht unbedingt notwendig sind.
Die gerade ausgeführten Konzepte brauchen dringend eine Erläuterung. Sie werden daher anhand eines längeren Beispiels nochmals ausführlicher beleuchtet.
Jetzt sind wir startklar! Sie wissen, was Sie im Buch erwartet und wo Sie was finden.
Sie müssen nur noch entscheiden, wo Sie anfangen wollen zu lesen: Wollen Sie den neuesten Hypes folgen? Dann empfehle ich eines der Kapitel aus Teil IV. Oder wollen Sie erst einmal schauen, was eigentlich wirklich hinter den »normalen« und scheinbar offensichtlichen Patterns wie Layers steckt? Dann fangen Sie mit Kapitel 7 an. Persönlich möchte ich Ihnen ans Herz legen, Kapitel 6 nicht zu lange zu verschieben, denn die Daten sind in vielen Fällen der eigentlich wertvolle Kern der Anwendung und bestimmen den langfristigen Erfolg stark mit.
Wie auch immer Sie sich entscheiden: Ich wünsche Ihnen viel Spaß und gute Erkenntnisse für Ihre nächsten Projekte!
1 Der Einfachheit halber benutze ich ab jetzt immer männliche Bezeichnungen. In meinen Seminaren merke ich aber aufgrund der durchdachten Beiträge: Es sollte viel mehr Software-Architektinnen geben!
Teil I
IN DIESEM TEIL…
In dieses Buch dreht sich alles um die technische Seite von Software-Architektur – aus dem einfachen Grund, dass meine Studierenden mir später zurückgemeldet haben, dass sie dieser Teil meiner Vorlesungen und Seminare im Beruf am meisten weitergebracht hat. Außerdem ist die Technik einfach unglaublich spannend.
Aber Software-Patterns und -Stile kann man nicht als Kochbuch lesen nach dem Motto: »Wenn Sie einen saftigen Schweinsbraten essen möchten, kochen Sie wie auf Seite 147 beschrieben. Für den aktuell angesagten Grünkernburger nutzen Sie dagegen das Rezept auf Seite 220.« Software-Architekturen werden getrieben vom Projektkontext, in dem sie entwickelt werden, und von den Zielen ganz unterschiedlicher Interessensgruppen. Außerdem müssen Software-Architekten andauernd Entscheidungen treffen, von denen es häufig abhängt, ob diese Ziele erreicht werden – und damit auch, ob das Projekt am Ende erfolgreich ist.
Daher beschäftigt sich der erste Teil mit den – verglichen mit der Technik – scheinbar »weicheren« Faktoren von Software-Architektur, von den verschiedenen Bereichen des Gebiets über die Rolle des Architekten bis hin zu einem geeigneten Mindset, um die notwendigen Entscheidungen zielsicher anzugehen.
Kapitel 1
IN DIESEM KAPITEL
Die Leistungen von Software-ArchitekturDie Rolle des Software-ArchitektenSoftware wird schnell sehr komplex. Sogar wenn die Aufgabe am Anfang einfach aussieht, wird sie später schnell größer, weil im Produktivbetrieb Sonderfälle auftauchen oder die Benutzer von der laufenden Anwendung inspiriert werden, weitere Arbeitsschritte zu digitalisieren. In vielen Fällen ist die Aufgabenstellung aber schon zu Beginn komplex. So oder so brauchen wir einen strategischen Plan für die Entwicklung.
Software-Architektur beschäftigt sich damit, solche strategischen Pläne bereitzustellen und über die Lebensdauer der Software weiterzuentwickeln. In diesem ersten Kapitel schauen wir darauf, was sie dazu alles leisten muss.
Allerdings soll es dabei in den Beispielen nicht schon zu technisch zugehen, sonst müssten Sie ja dauernd vorausblättern in die späteren Kapitel. Stattdessen nehmen wir Beispiele aus einer Metapher: Die Entwicklung einer Software-Anwendung ist in vielen Aspekten ähnlich dem Bau einer Schule. So wie die meiste Software ist eine Schule vor allem ein Funktionsbau. Das, was dort geleistet werden muss, um eine brauchbare Schule zu erhalten, muss in analoger Form auch für Software geleistet werden. Diese Analogie ist tatsächlich nicht ganz neu: Die Patterns-Community sieht sich bekanntlich in der Tradition des Architekten Christopher Alexander und seiner Ideen, wie man zu guten Gebäuden kommt [7].
Wir wollen also eine Schule bauen und dafür einen großen Gesamtplan entwerfen. Dieser Plan muss natürlich viele ganz verschiedene Dinge festlegen, von der Anzahl und Größe der Klassenräume über die Lage und Größe des Lehrerzimmers bis zur Einhaltung von Vorgaben zur Beleuchtung. Auch Details wie die Lage und Anzahl von Steckdosen muss der Architekt schon mitbedenken, denn die hängen oft eng mit der geplanten Raumnutzung zusammen. Es wird also ein sehr vielschichtiger Plan.
Im Zentrum der Planung stehen natürlich die funktionalen Anforderungen (engl. functional requirements): In der Schule soll vor allem effektiv unterrichtet und gelernt werden. Alles, was dazu notwendig ist, muss in der Schule vorhanden sein. Alle Anforderungen aufzulisten, ist allerdings gar nicht so einfach: Zunächst braucht man Klassenräume mit genug Platz je Schüler, klar. Dann braucht man Flure, die die Klassenräume verbinden, klar. Dann sanitäre Einrichtungen, Lehrerzimmer, einen Raum für Kopierer, klar. Und natürlich auch einen Server-Raum und überall Schächte für Netzwerkkabel. Vielleicht Freiarbeitsflächen für spezielle pädagogische Konzepte. Eine Cafeteria für Nachmittagsunterricht und Ganztagsangebote. Labore für Physik und Chemie. Und und und.
In der Software-Architektur ist eine möglichst vollständige Übersicht über die funktionalen Anforderungen deshalb wichtig, weil sie ja darüber bestimmten, welche Aufgaben die Software technisch lösen muss. Und diese Aufgaben werden auf verschiedene Komponenten oder Module der Software verteilt, sodass indirekt auch die Struktur mitgeprägt wird.
Der Teilbereich des Requirement Engineering kümmert sich um solche Fragen. Es kommt darauf an, zu Beginn des Projekts wirklich gründlich nach Anforderungen zu suchen und in den einzelnen Iterationen während des Projekts schnell auf neue und geänderte Anforderungen aufmerksam zu werden. Einige mögliche Quellen für funktionale Anforderungen sind:
Use-Cases
: In welchen Situationen und mit welchem Zweck wollen Benutzer mit dem System interagieren? Was geben sie ein? Welche Reaktionen erwarten sie?
Anwendungsgebiet (
Application-Domain
): Welche Aufgaben müssen typischerweise von Fachleuten in dem Bereich gelöst werden, in dem die Software eingesetzt werden soll?
Unternehmerische Ziele (
Business-Drivers
): Warum schreiben wir die Software überhaupt? Welche wirtschaftlichen Vorteile soll sie bringen?
Im Fall der Schule wären die entsprechenden Fragen: Wie wird unterrichtet? Welche Aufgaben haben Lehrer und Schüler im Schulbetrieb? Wie gehen wir mit den steigenden Schülerzahlen nach dem Zuzug vieler Familien um?
Wenn man ein Gebäude einen »funktionaler Zweckbau« nennt, ist damit gemeint: Ist schon okay, aber keiner geht gern hin, und hässlich ist es obendrein. Es reicht nicht, eine Schule zu bauen, in der unterrichtet werden kann, wenn die Randbedingungen nicht stimmen: lange Wege zwischen Räumen, hässliche Betonwände, zugige Fenster, häufiger Ausfall der Heizungsanlage, hohe Betriebskosten …Mit so einer Schule kann niemand etwas anfangen.
Mit der Software ist es genauso: Über die funktionalen Anforderungen hinaus gibt es nicht-funktionale Anforderungen (engl. Non-functional Requirements), die die Software erreichen muss. Weil ihre Bezeichnungen im Englischen fast immer auf »-ility« enden, heißen sie salopp auch »die -ilities«. Wenn es mehr darauf ankommt, die Software selbst zu beschreiben, nutzt man den Begriff nicht-funktionale Eigenschaften (Non-functional Properties). Teilweise kann man die nicht-funktionalen Anforderungen auch als Qualitätsmerkmale (engl. quality attributes) sehen, weil sie etwas darüber aussagen, wie gut die Software die funktionalen Anforderungen umsetzt. Ein alternativer Begriff ist Architectural Characteristics, denn sie werden hauptsächlich durch die gewählte Software-Architektur bestimmt. Damit ist auch klar: Ein Software-Architekt sollte die »ilities« immer genau im Blick behalten.
Eine auch nur halbwegs vollständige Liste anzugeben, dafür reicht der Platz nicht, und es wäre außerdem recht leserunfreundlich, weil trocken. In der späteren Beschreibung der Architektur-Ansätze werden die jeweils relevanten nicht-funktionalen Eigenschaften besprochen. Deshalb hier nur eine grobe Gruppierung mit einigen Beispielen:
Laufzeit-Anforderungen:
Availability
: Welchen Anteil der Zeit ist das System verfügbar? Können Updates ohne Unterbrechung eingespielt werden?
Responsiveness
: Wie lange muss ein Benutzer auf eine Reaktion warten?
Robustness
: Wie gut geht das System mit speziellen Ereignissen wie unerwarteten Eingaben oder Netzwerkausfällen um?
Scalability
: Wie leicht kann die Anwendung für sehr viel mehr Zugriffe ausgelegt werden?
Strukturelle Anforderungen:
Maintainability
: Wie leicht können im Nachhinein Anpassungen vorgenommen werden?
Extensibility
: Wie leicht können neue Funktionen ergänzt werden?
Testability
: Wie einfach können einzelne Module oder Komponenten oder das Gesamtsystem getestet werden?
Reusabilty
: Können Teile des Systems in anderen Projekten wiederverwendet werden?
Querschnitts-Anforderungen:
Usability
: Wie einfach ist das Erlernen und wie sicher und gern arbeiten die Benutzer mit dem System?
Privacy
: Wie weitgehend können Vorgänge und Daten verborgen werden?
Legal Requirements
: Beachtet die Software alle relevanten rechtlichen Regelungen?
Traceability
: Findet man die funktionalen Anforderungen in der Software-Struktur wieder?
Nicht-funktionale Eigenschaften sind deshalb besonders wichtig, weil sie häufig missionskritisch sind und über den Projekterfolg entscheiden: Eine konzernweite Anwendung, die in Tests perfekt funktioniert, aber nicht für die 20.000 weltweit verteilten Benutzer skalierbar ist, ist wertlos. Gleichzeitig bestimmen sie stark die Architektur und Struktur mit, sodass man sie genauso sorgfältig sammeln muss wie die funktionalen Anforderungen. Weil jede Anforderung aber einen gewissen Mehraufwand mit sich bringt und sich die verschiedenen Anforderungen manchmal auch widersprechen, muss der Architekt außerdem sinnvoll priorisieren.
Bei einer Schule wollen alle mitreden: der Kreis wegen der Baukosten, die Stadt wegen der Bebauungspläne, der Bürgermeister wegen des Prestiges, die Schulleitung und Lehrer wegen der Pädagogik, der Hausmeister wegen des Pausenverkaufs …Die Liste ist endlos. Am Ende muss es aber eine einzige Schule für alle geben.
Bei der Software-Erstellung ist es nicht anders: Viele verschiedene Interessengruppen (engl. stakeholder) wollen Einfluss nehmen und die Architektur muss die unterschiedlichen Anforderungen und Wünsche priorisieren und gegeneinander abwägen. Wie findet man aber die relevanten Stakeholder und ihre Anforderungen? Hier sind einige Ansätze:
Verschiedene
Benutzergruppen
(engl.
user groups
) haben jeweils eigene Use-Cases und Anforderungen an das System. Mit einer Liste der Benutzergruppen zu starten, ist sicher keine schlechte Idee.
Weil Beschreibungen von Benutzergruppen oft abstrakt bleiben, übersieht man leicht einige ihrer Anforderungen. Eine
Persona
dagegen ist ein prototypischer (engl.
archetypical
) Benutzer, den man sehr detailliert und individualisiert beschreibt. Damit werden implizite Erwartungen besser vorstellbar. Verschiedene Personas, die klassisch zu einer Benutzergruppe gehören würden, werden unterscheidbar.
Eine andere Möglichkeit der Konkretisierung sind
Key Users
. Man wählt pro Benutzergruppe einige Mitarbeiter aus, die etwa besondere Fachkompetenzen haben oder gern strategisch denken und handeln.
Ein Blick lohnt auch auf die mit der Umsetzung des Projekts beschäftigen Personen: Die Entwicklungsteams und das Projektmanagement haben selbst auch Anforderungen, zum Beispiel zuverlässige und motivierende Fortschritte, interessante Aufgaben oder eine verträgliche Arbeitslast.
Die Kunden des Unternehmens, auch wenn sie das System nicht selbst bedienen, sind von seiner Leistung oft indirekt abhängig, zum Beispiel wenn Bestellprozesse mit der Software anders ablaufen oder neue Funktionen bieten.
Das allgemeine Management und die Unternehmensführung haben die wirtschaftliche Seite des Projekts im Blick, also Budget, Kosteneinsparungen oder Gewinn durch die Software. Auch Besitzer und Anteilseigner des Unternehmens, die ja letztlich das Kapital für die Entwicklung bereitstellen, haben Interessen.
Kooperationspartner in anderen Abteilungen oder anderen Unternehmen sind vielleicht auf Schnittstellen oder bestimmte Zugriffswege angewiesen.
Bei einigen Projekten sind Behörden und andere Regulierungsorganisationen beteiligt. Beispielsweise stellt das Finanzamt ziemlich viele Anforderungen an die elektronische Buchhaltung und das Dokumentenmanagement.
Mit einer
Empathy Map
kann man schließlich die impliziten und emotionalen Erwartungen von identifizierten Stakeholdern herausarbeiten, zum Beispiel um Usability-Faktoren zu identifizieren.
Sie sehen schon: Es ist nicht einfach, schon allein alle Stakeholder eines Projekts zu identifizieren. Am Ende ist es immer eine Person oder Personengruppe, die direkt oder indirekt vom Fortgang und Erfolg des Projekts und der Einführung der Software betroffen ist. Weil das potenziell sehr viele sind, ist das Stakeholder Management oder die Stakeholder Analysis eine ganz eigene und wichtige Aufgabe der Software-Architektur. Ein Projekt kann nicht nur an Technik oder Budget scheitern, sondern auch daran, dass man einen wichtigen Stakeholder oder eines seiner fundamentalen Bedürfnisse übersehen hat.
Wenn wir wissen, welche Aufgaben die Schule übernehmen soll und wer daran welches Interesse hat, geht es an die Gebäudeplanung: Welche Räume sehen wir vor? Wo wird kopiert? Wo werden Chemie-Versuche vorbereitet? Wo läuft der Pausenverkauf? Dabei geht es auch um dynamische Abläufe: Schaffen es die Lehrer in der 5-Minuten-Pause zum Lehrerzimmer und dann in die nächste Klasse? Wie kommen die Schüler trocken zum separaten naturwissenschaftlichen Trakt? Sind die Schulbusse sicher zu erreichen?
Auf der Software-Seite verteilen wir Teilaufgaben auf verschiedene Software-Elemente, wie etwa Komponenten, Module, Services, Klassen oder Methoden. Die gewählte Struktur drückt also ein bestimmtes Problem- und Lösungsverständnis aus, und schon in der Architektur muss man immer mitdenken, wie die Implementierung später aussieht.
Fast noch wichtiger ist aber, dass die Struktur mitbestimmt, welche nicht-funktionalen Anforderungen erfüllt werden. Beispielsweise erhöht sich die Maintainability – also die spätere Änderbarkeit der Software –, wenn wir inhaltlich eng zusammengehörige Funktionselemente in einem Modul zusammenfassen, während unabhängige Elemente auf verschiedene Module aufgeteilt werden. Weil Änderungen häufig nur die Details einzelner Anwendungsfunktionen betreffen, bleiben sie dann auf ein Modul beschränkt. Unter dem Slogan Low Coupling, High Cohesion ist diese Idee weit verbreitet.
Architektur-Patterns und Architektur-Stile fassen Erfahrungen mit bestimmten Aufteilungen von funktionalen Aspekten zusammen. Besonders heben sie hervor, in welcher Situation und unter welchen Voraussetzungen ein Pattern oder ein Stil sinnvoll angewendet werden kann und welche nicht-funktionalen Eigenschaften man dann erwarten darf. Der größte Teil dieses Buchs beschäftigt sich mit Patterns und Stilen, ihrem Aufbau und ihren Konsequenzen.
Wenn wir bei der Schule bleiben, wäre ein Pattern: Sieh auf jedem Stockwerk am Ende eines Ganges Toiletten-Räume vor. Eine Aufteilung von Funktionen wäre: Der Kopierraum ist neben dem Lehrerzimmer, aber wegen der Geräuschentwicklung mit einer Tür abgetrennt.
Die Software-Struktur hat aber nicht nur technische, sondern auch organisatorische Konsequenzen: Jedes Software-Element wird im Normalfall von einem einzelnen Team betreut. Damit gibt die Software-Struktur gleichzeitig die Arbeitsverteilung vor (engl. work breakdown structure). Ein umgekehrtes Phänomen, das Architekten kennen und beachten sollten, ist Conway's Law: Organisationen neigen dazu, die technische Funktionsverteilung entlang ihrer vorhandenen Organisationsstrukturen festzulegen. Teams werden also nicht für ein Projekt neu zusammengestellt, sondern die Software muss so strukturiert werden, dass die bestehenden Teams Teile übernehmen können. Diese politische Entscheidung nimmt natürlich keine Rücksicht auf die funktionalen und nicht-funktionalen Anforderungen, was zum Problem werden kann.
Wenn es die eine, ideale Schule gäbe, wären plötzlich viele Architekten arbeitslos. Dann würde man vielleicht 10–20 Typen für unterschiedliche Schülerzahlen einmal ausarbeiten und immer wieder genau so bauen. Aber weil die lokalen Gegebenheiten, vom Bauplatz bis zum pädagogischen Konzept, jeweils variieren, ist das einfach nicht möglich.
In der Software-Architektur gibt es genauso nie die eine richtige Lösung. Jede Entscheidung für eine bestimmte Struktur zieht beispielsweise unterschiedliche nicht-funktionale Eigenschaften nach sich, und je nach Priorisierung im konkreten Projekt kann die eine oder andere Entscheidung sinnvoller sein. Der Begriff Forces erfasst die verschiedenen Einflüsse, die die Entscheidung in die eine oder andere Richtung bewegen. Die Trade-offs sind die Abwägungen zwischen Einflüssen und Ergebnissen. Manchmal sind die Vorteile einer Lösung besonders stark, dann hat man Glück gehabt und braucht die anderen nur kurz anzudenken – aber das sollte man dann auch tun.
Zwei Schlagworte haben sich für diese Herausforderung eingebürgert:
No Silver Bullet
: Man kann nicht erwarten, dass durch irgendeinen Ansatz oder irgendeine Technologie plötzlich wirklich harte Probleme gelöst werden.
No-Free-Lunch
-Theorem: Wenn man auf einer Seite Gewinne macht, dann muss man auf der anderen Seite irgendetwas dafür bezahlen.
Ich habe für mich einen dritten Ausdruck gefunden, der mir mehr den Hintergrund ins Gedächtnis ruft:
Komplexität kann man nicht wegzaubern
: Wenn ein komplexes Problem gelöst werden muss, dann muss die Software so oder so Mechanismen enthalten, um es zu lösen. Für diese Mechanismen muss dann eben auf die eine oder andere Art bezahlen, egal für welche Lösung man sich am Ende entscheidet.
Für den Architekten ist es wichtig, die Komplexität und die Herausforderungen im Projekt aktiv zu suchen und früh zu identifizieren. Sonst kann er die Forces nicht in seine Überlegungen einbeziehen. Es funktioniert also langfristig nicht, mit zu viel Optimismus nur auf die Sonnenseiten, die offensichtlichen Aufgaben und die »Low-hanging Fruits« zu schauen.
Eine Schule mit modernen Glasfronten, großzügigen Räumen, geschwungenen Treppen und einladender Aula sieht natürlich in den computer-gerenderten Ansichten einfach repräsentativ und attraktiv aus. Wenn auch noch die pädogischen Konzepte in flexiblen und die Kreativität anregenden Lernlandschaften umgesetzt sind und nebenbei die neueste Wärmedämmung niedrige Betriebskosten verspricht, dann steht dem Gewinn der Ausschreibung nichts mehr im Wege. Umso ärgerlicher, wenn nachher bei der Ausführung an allen Ecken und Enden auf Kosten der Qualität gespart werden muss und es bei Regen durch das undichte Deckenlicht ins Atrium nicht tröpfelt, sondern gießt.
Eine Software-Architektur bildet die Grundlage für Design und Implementierung. Sie gibt die großen Strukturen vor, innerhalb derer die Entwickler dann Schnittstellen und Klassen ausarbeiten. Wenn diese Strukturen aber gar nicht technisch umgesetzt werden können, weil der Architekt entscheidende Details übersehen hat, führt das zu Mehraufwand für Umarbeitungen. Außerdem ist der Code langfristig weniger wartbar, weil er nur lokal durchdachte Ad-hoc-Strukturen nutzt, die nicht zur dokumentierten Architektur passen. Es ist also die Aufgabe von Architektur, das Design und an missionskritischen Stellen, wenn beispielsweise viele Nutzer einen hohen Durchsatz an Anfragen erfordern, auch die Implementierung bis hin zur Mechanical Sympathy vorauszudenken und zu evaluieren.
Es gibt Architekturbüros, die bauen häufiger Schulen und werden immer angefragt, wenn irgendwo in der Gegend eine neue Schule zu bauen ist. Dann sprechen sie mit allen Beteiligen, bringen ihre eigene Erfahrung ein und legen nacheinander Konzepte, Entwürfe und Werkpläne vor. Auf dieser Grundlage werden dann die einzelnen Gewerke ausgeschrieben und am Ende die Schule gebaut.
Ein Software-Architekt muss natürlich dafür sorgen, dass die Architektur die vorher beschriebenen Aufgaben im Projekt erfüllen kann. Aber wie arbeitet er im Projekt?
Im klassischen Wasserfallmodell ist die Rolle des Architekten ganz ähnlich wie beim Schulbau: Er ist dafür verantwortlich, …
die Stakeholder zu identifizieren
deren Anforderungen und Wünsche aufzunehmen und zu analysieren
die umzusetzenden Anforderungen zu definieren und zu priorisieren
eine Gesamtstruktur aus Komponenten und Modulen zu schaffen
die Verbindungen zwischen den Komponenten vorzugeben
die Erreichung der nicht-funktionalen Eigenschaften zu analysieren
die Aufteilung der Arbeit auf Teams zu planen
das Ergebnis dieser Überlegungen präzise festzuhalten und an die Entwickler für die weitere Arbeit zu übergeben.
In diesem Modell läuft also der Informationsfluss nur in eine Richtung: Vom Architekten zu den Entwicklern. Bestenfalls hat er bei seiner Tätigkeit schon zukünftige Änderungen oder Erweiterungen vorausgedacht. In jedem Fall ist aber die Arbeit des Architekten im Wesentlichen getan, sobald das Architektur-Dokument abgenommen ist.
Tatsächlich stimmt es nicht, dass der Schularchitekt so vorgeht wie im vorherigen Abschnitt angedeutet. Von einer befreundeten Architektin, die öfter Schulen baut, weiß ich, wie oft sie auf den Baustellen unterwegs ist und dort mit den Handwerkern die Details der Ausführung durchspricht und mit den Plänen abgleicht. Falls möglich führt sie auch noch Änderungen an den Plänen durch, wenn der Bauherr es sich in letzter Minute anders überlegt.
Auch der Software-Architekt bleibt heute im Projekt und hat bis zum Ende eine aktive Rolle.
Er coacht die Teams und überwacht die Umsetzung der Architektur, besonders die Verbindung mit dem Design.
Er nimmt Feedback der Entwickler in die Architektur auf, vor allem, wenn sich durch Design-Entscheidungen der Entwickler Änderungen an der Architektur ergeben.
Er überarbeitet und erweitert die Architektur in agilen Projekten von Iteration zu Iteration und passt sie den neuen Zielen und Priorisierungen an.
Er behält immer ein Gefühl für die Implementierung, um die Auswirkungen seiner Entscheidungen und möglicher Trade-offs zu verstehen.
Der letzte Punkt ist besonders wichtig, weil eine Architektur natürlich auch effektiv umsetzbar sein muss, um Laufzeit und Budget des Projekts einzuhalten. Am einfachsten ist es natürlich, wenn der Architekt Teile des Codes selbst schreibt. Wenn er allerdings zu sehr Mit-Entwickler wird, kann das problematisch sein, denn seine eigentliche Aufgabe, für die er auch den Großteil seiner Zeit aufwendet, ist ja die Architektur und die Kommunikation mit allen Stakeholdern in vielen Meetings. Um eine Balance zu finden, helfen folgende Strategien:
Der Architekt schreibt keinen Code im kritischen Pfad des Projekts. Dieser Code gehört dem Team, damit er weiterentwickelt werden kann, auch wenn der Architekt gerade nicht greifbar ist. Besonders betrifft das zentrale Frameworks, bei denen allerdings die Versuchung besonders groß ist, weil der Architekt sie ja erdacht hat und zu Beginn am besten versteht. Da hilft nur Coaching.
Der Architekt schreibt Proof-of-Concept-Prototypen, mit denen er Architektur- und Design-Entscheidungen validiert. Auch wenn der Code selbst nicht produktiv verwendet wird, sollte er trotzdem eine hohe Qualität haben, weil Entwickler ihn wahrscheinlich als Blaupause nutzen.
Der Architekt schreibt Teile der Business-Logik. Sie ist das tägliche Brot der Entwickler und bestimmt damit den Aufwand und den Projekterfolg maßgeblich mit. Der Architekt sollte daher ein gutes Gefühl dafür haben, wie effektiv sie geschrieben werden kann.
Der Architekt geht in Code-Reviews zusammen mit den Entwicklern größere Teile der Implementierung durch und hört aufmerksam auf ihr Feedback. So bekommt er wenigstens passiv einen Eindruck von der täglichen Arbeit.
Am Ende geht es darum, dass der Architekt Teil des Teams bleibt und einen starken Eindruck davon gewinnt, wie sich Architektur-Entscheidungen auf die Entwicklung tatsächlich auswirken und wie Änderungen der Architektur gefühlte Schmerzpunkte beheben können. Und natürlich ist konkreter Code auch eine sehr direkte Art des Coachings, das zu verbessertem Design und einer klareren Implementierung führt.
Einen sehr vollständigen Überblick über die Konzepte, Begriffe und Methoden der Software-Architektur finden Sie in [10]. Das Buch war in den 1990ern eines der Ersten zum Thema und wird seitdem fortlaufend aktualisiert. Einen Hands-on- Überblick aus Sicht eines erfahrenen Architekten gibt [89], sowohl über Konzepte als auch über aktuelle Stile und Patterns. Eine moderne Sicht auf Strategien für Architektur und Design finden Sie in [73]; weil weniger konkrete Software-Strukturen besprochen werden, braucht man ein wenig eigene Entwicklungserfahrung.
Kapitel 2
IN DIESEM KAPITEL
Wie innere Einstellungen Architektur-Entscheidungen beeinflussenWelche inneren Einstellungen dabei hilfreich sindSoftware-Architekten müssen andauernd Entscheidungen treffen, denn es gibt eigentlich nie nur eine Lösung für eine Aufgabenstellung. Die Entscheidungen ziehen sich von den großen Strukturen über die Auswahl von Produkten und Frameworks bis zu Schnittstellen zwischen Komponenten und oft auch in das Design der Komponenten hinein.
Wie wir Entscheidungen treffen, hängt aber oft ganz wesentlich von grundsätzlichen Einstellungen ab, die gar nichts mit der konkreten Fragestellung zu tun haben: Sind wir eher konservativ oder sind wir neugierig und probieren gern neue Wege aus? Wie viel Risiko ist uns ein möglicher Gewinn wert? Tolerieren wir eine längere Durststrecke, wenn wir am Ende eine große Belohnung erwarten? Suchen wir perfektionistisch nach der besten Lösung oder halten wir es eher mit dem Pareto-Prinzip? Lassen wir uns schnell von Ideen begeistern oder sind wir eher skeptisch und warten erst einmal ab, ob sich die Idee bewährt?
Die Einstellungen, mit denen wir Aufgaben angehen, werden gern unter dem Begriff Mindset zusammengefasst. Genauso wenig, wie es in der Software-Architektur die eine »richtige« Lösung gibt, gibt es das eine »richtige« Mindset. Deshalb ist es gut und wichtig, dass in Teams ganz unterschiedliche Charaktere zusammenkommen, um gemeinsam strategische Entscheidungen abzuwägen. Diversity hat auch in der Entwicklung Einzug gehalten. Als Architekt sollte man sich sein eigenes Mindset bewusst machen, um seine eigenen Architektur-Entscheidungen zu hinterfragen und zu bewerten.
Dieses Kapitel sammelt Elemente eines sinnvollen Mindsets für Software-Architekten, die üblicherweise in der Literatur eher zwischen den Zeilen oder in Nebenbemerkungen behandelt werden. Einige der Punkte widersprechen sich. Besser sollte man sagen: Sie balancieren sich so aus, dass sie zusammen eine Lenkung hinbekommen. Neben der eigenen Reflexion helfen die Elemente auch bei der Einschätzung von Informationen, die man zu Architekturen findet: Wenn man sie im Hinterkopf hat, sieht man schneller, welche Punkte eines Autors man wie hinterfragen sollte, um eine ausgewogene Gesamtsicht zu bekommen.
In diesem Kapitel nenne ich Konzepte und Technologien, die später im Buch noch behandelt werden, ausnahmsweise ohne Vorwärtsverweise, damit der Text nicht unleserlich wird. Für den Überblick reicht ein ungefähres Verständnis der Begriffe aus. Wenn es Sie an einer Stelle dringend interessiert, lesen Sie aber gern einmal die Einleitung zum jeweiligen Kapitel oder Abschnitt voraus.
Software wird eigentlich immer mit einem einzigen Ziel geschrieben: um damit Geld zu verdienen. Das kann direkt durch Lizenzverkäufe oder im Open-Source-Bereich indirekt durch Support-Dienstleistungen passieren. Sehr häufig passiert es aber auch implizit, wenn unternehmensinterne Anwendungen den Umsatz steigern, indem sie Kernprozesse skalierbar machen, oder indem sie Arbeitsabläufe vereinfachen und dadurch die Kosten reduzieren. Wie sich die IT-Spezialisten innerhalb eines Unternehmens wahrnehmen, hat entscheidenden Einfluss darauf, ob das am Ende gelingt. Und das gilt natürlich besonders für Software-Architekten, die durch strategische Entscheidungen wesentlich zum unternehmerischen Erfolg von Software beitragen oder eben nicht.
Wenn man mit Software am Ende Geld verdienen möchte, dann muss die Entwicklung von Anfang an den unternehmerischen Wert (engl. business value) der Software im Blick behalten. Und dieser Wert bemisst sich natürlich stark daran, wie das Unternehmen selbst Gewinne erwirtschaftet, oder moderner gesagt: was sein Geschäftsmodell (engl. business model) ist.
Ein Architekt sollte sich deshalb aktiv um diese Fragen Gedanken machen und entsprechend mit der Führungsebene des Unternehmens sprechen. Es reicht nicht aus, die Anforderungen der Fachanwender präzise aufzunehmen und umzusetzen, denn die orientieren sich häufig mehr am aktuellen Zustand und einer bequemen Handhabung als an der Frage, wie das Unternehmen in 3 bis 5 Jahren Geld verdienen wird. Speziell kann es etwa um folgende Fragen gehen:
Welche Funktionalitäten werden priorisiert, um den Markteintritt innerhalb eines bestimmten Zeitfensters zu schaffen?
Welche Teile der Software müssen flexibel gehalten werden, um Wünsche bestimmter Kundengruppen später genau abbilden zu können?
Wie viel sind potenzielle Kunden bereit, für eine bestimmte Leistung zu zahlen, die nur mit Software-Unterstützung angeboten werden kann?
Wie schnell rechnet sich eine bestimmte Investition? Wenn man beispielsweise Teile einer monolithischen Anwendung in Microservices überführt, dann ist das im ersten Schritt sehr aufwendig. Die Auswahl der Teile orientiert sich am unternehmerischen Wert, den der Gewinn an Flexibilität durch separate Services mit sich bringt.
Wie können wir die in Prozessen anfallenden Daten so sammeln und aufbereiten, dass sie unternehmerische Entscheidungen unterstützen?
Es gibt also viel zu bedenken, das über die reine Funktionalität und auch über nicht-funktionale Eigenschaften hinausgeht.
Lange Zeit waren IT-Abteilungen vor allem Kostenstellen (engl. cost centers): PCs und Großrechner, Netzwerke und Anwendungen waren halt notwendig, um zu arbeiten. Und das muss das Unternehmen dann halt zahlen, so wie es vielleicht die Straßen und Gebäude auf dem Werksgelände instand hält.
Mit der fortschreitendenden Digitalisierung sind IT-Abteilungen mehr und mehr Profit-Center, erwirtschaften also selbst zumindest indirekt Gewinne: Datensammlungen verbessern unternehmerische Entscheidungen, helfen bei der Kundenansprache oder sind vielleicht sogar selbst ein Produkt. Und mit Software skalieren die Kernprozesse des Unternehmens und das treibt den Umsatz. Oder die Unterstützungsprozesse werden effizienter und die Kosten sinken.
Der Software-Architekt sollte sich entsprechend fragen: Mit welchen Funktionen kann meine Anwendung ganz konkret wie viel Geld verdienen? Dabei kann er als Experte oft auch Vorschläge für mögliche Szenarien machen, die die Nicht-ITler der Führungsebene noch gar nicht im Blick hatten.
Natürlich ist Software-Entwicklung immer sehr kostenintensiv. Wenn ein Software-Architekt nach der »besten« Lösung für ein Anwendungsproblem sucht, muss er häufig zwischen kurz- und mittelfristigen Kosten und möglichen langfristigen monetären Vorteilen abwägen. Soll er beispielsweise eine Microservice-Architektur aufsetzen, die langfristig eine bessere horizontale Skalierbarkeit bietet, aber durch aufwendigere Entwicklung und komplexes Monitoring kurzfristig höhere Kosten verursacht als ein Monolith? Sollte er in den Betrieb einer Messaging-Infrastruktur investieren, mit dem Ziel, nach und nach die Anwendung als asynchron kommunizierendes reaktives System zu realisieren?
Diese Entscheidungen hängen natürlich davon ab, welche Benutzerzahlen mittel- und langfristig prognostiziert sind und wie wahrscheinlich es ist, dass diese Prognosen tatsächlich eintreffen. Wichtig ist nur: Die entstehenden Kosten sind immer ein entscheidender Aspekt auch in der Abwägung zwischen rein technischen Realisierungsalternativen. Man sollte sie realistisch betrachten, genauso wie man die umsetzbaren nicht-funktionalen Eigenschaften für die verschiedenen Alternativen realistisch betrachtet.
Architekten müssen natürlich im Grunde ihres Herzens Optimisten sein und an den Projekterfolg glauben, sonst könnten sie den Job nicht machen. Auf dem Weg dahin ist aber zu viel Optimismus oder Begeisterung bei einzelnen Architektur-Entscheidungen nicht immer angebracht.
Architektur beschäftigt sich häufig mit sehr großen und missionskritischen Anwendungen. Und in diesem Zusammenhang ist die Einstellung, dass eine Software mit 99,99% Zuverlässigkeit doch super ist, oft nicht gut genug: Wenn nach 100.000 Online-Bestellungen beim Jahresabschluss 10 Rechnungen nicht mehr auffindbar sind, weil die Netzwerkkommunikation zwischen Services leider manchmal Probleme macht, dann sind Buchhaltung und Wirtschaftsprüfer in heller Aufregung, weil sie das bei der nächsten Außenprüfung dem Finanzamt erklären müssen.
Daher sollten es Architekten mit Murphy's Law halten und annehmen, dass alles, was schiefgehen kann, auch irgendwann schiefgehen wird. Im Software-Fall kommt noch eine Besonderheit hinzu: Manche Probleme zeigen sich erst mit steigender Auslastung des Systems. Zum Beispiel treten Deadlocks in Datenbanken oft erst bei vielen gleichzeitigen Transaktionen auf oder ein Server-Prozess stürzt plötzlich ab, weil bei vielen gleichzeitigen Anfragen irgendeine Ressource überbelastet wird. Außerdem können Timing-Aspekte dazukommen: Unter Last steigen die Latenz des Netzwerks und die Antwortzeiten einzelner Services, woraufhin andere Teile der Anwendung einen Timeout registrieren und Fehler melden, anstatt Prozesse richtig zu Ende zu führen.
Wie weit man diese Einstellung treiben kann und manchmal sollte, zeigen manche großen Player der Tech-Industrie, die ihre Anwendungen in Test-Setups regelmäßig überlasten oder zufällig einzelne Anwendungsteile zeitweilig abstürzen lassen, nur um zu schauen, wie die Gesamtanwendung darauf reagiert.
Aber diese Einstellung hat natürlich Grenzen, daher geht es eben um gesunde Paranoia: In vielen Bereichen ist vielleicht 99,99% Zuverlässigkeit eben doch ausreichend. Wenn man beispielsweise aus Angst vor der unvollständigen Transaktionalität von NoSQL-Datenbanken den Warenkorb im Onlineshop in einer relationalen Datenbank ablegt, kauft man sich ein unnötiges Bottleneck ein: Wenn in Ausnahmefällen etwas schiefgeht, lädt der Benutzer vielleicht einfach die Seite noch mal, und alles ist wieder in Ordnung. Nur beim rechtsverbindlichen Kauf ganz zum Schluss brauchen wir mehr Zuverlässigkeit, aber das passiert ja nur relativ selten und dann ist auch eine transaktionale Verarbeitung machbar und sinnvoll.
In der Architektur gibt es grundsätzlich nicht die eine perfekte Lösung, und Gewinne an einer Stelle muss man fast immer durch Mehraufwand und erhöhte Komplexität an anderer Stelle einkaufen: No Silver Bullet und No Free Lunch eben.
Auf der anderen Seite lebt der Fortschritt der Software-Architektur von begeisterten Fürsprechern neuer Technologien (engl. technology evangelists), die mit einem bestimmten Ansatz in Projekten gute Erfahrungen gemacht haben und diese anschließend verbreiten. Und natürlich stellen Frameworks auf ihren Websites und in zugehörigen Blogs erst einmal die besonderen Leistungen heraus.
Für den Architekten ist es dann nicht immer ganz einfach, den Gewinn eines Ansatzes oder einer Technologie im eigenen Projekt realistisch einzuschätzen. Zum einen werden die Voraussetzungen von Erfolgen nicht immer klar dargestellt, beispielsweise das notwendige Vorwissen oder die Einarbeitungszeit im Team. Zum anderen werden selten die Einschränkungen und die Nachteile, beispielsweise in Form einer höheren Komplexität oder nicht mehr gangbarer klassischer Lösungen, herausgearbeitet.
Wenn man also eine Technologie analysiert und bewertet, sollte man immer skeptisch sein und Aussagen kritisch hinterfragen: Was kostet das scheinbare Free Lunch am Ende im Projekt? Welche Lösungselemente, die man in anderen Ansätzen als gegeben hinnimmt, werden vielleicht gar nicht unterstützt? Manchmal muss man auch mit eigenem Wissen hinter die Marketing-Geschichte schauen. Auf der Website einer NoSQL-Datenbank fand ich beispielsweise die Erklärung, dass die Vermeidung von Redundanz in relationalen Datenbanken vor allem dem teuren Speicher in früheren Zeiten geschuldet ist. Weil das heute natürlich keine Rolle mehr spielt, können wir endlich hochskalierbare NoSQL-Datenbanken nutzen. Aber das ist natürlich Quatsch: Die Redundanzvermeidung zielt vor allem auf Datenkonsistenz und Anomalievermeidung, und wenn man Redundanz zulässt oder sie sogar aus Effizienzgründen erforderlich ist, wird die Anwendungslogik für die Datenverwaltung komplexer.
Eine gesunde Skepsis bei der Technologie- und Framework-Auswahl ist auch deshalb immer angebracht, weil Hype-driven Development häufig in die Sackgasse führt. Die »moderne« Art, Dinge zu tun, ist nicht automatisch besser als die klassische und gut erprobte. Wenn ein Hersteller die FUD-Marketing-Strategie (Fear, Uncertainty, Doubt) bedient, sollte man sich lieber fragen, ob er keine besseren, positiven Argumente hat. Und wenn inhaltlich schwierige Ziele wie Decoupling, Flexibilität und Skalierbarkeit als quasi-automatische Folgen eines Ansatzes propagiert werden, sollte man besonders skeptisch sein.
Eine Anwendung ist nie ein Selbstzweck, sondern unterstützt von außen vorgegebene Ziele. Alles, was hilft, diese Ziele schneller und mit geringeren Kosten zu erreichen, ist willkommen. Dabei ist einiger Pragmatismus angebracht, beispielsweise in folgenden Fällen:
Eine etablierte Technologie mit einem großen Ökosystem, mit der sich das Team auskennt, hilft normalerweise mehr als eine moderne, gerade trendende Alternative, mit der das Team erst Erfahrung sammeln muss und von der noch nicht klar ist, ob sie in 5 Jahren noch weiterentwickelt wird.
Microservices skalieren zwar vielleicht langfristig besser und sind auch strategisch flexibler, aber zu Beginn vereinfacht ein Monolith das Deployment und ist auch flexibler, weil man die inneren Strukturen einfacher anpassen kann, ohne gleich Schnittstellen und Protokolle zu überarbeiten.
Wenn ein Ansatz performant genug ist für die erwarteten Nutzerzahlen, kann man ihn nehmen, auch wenn er nicht hochskalierbar ist. Oder wie Donald Knuth es bekanntlich formulierte:
Premature optimization is the root of all evil
.
Das richtige Werkzeug für den Job ist nicht immer das neueste, hippeste, sondern oft das, mit dem das Team am meisten Erfahrung hat. Die Möglichkeit, verschiedene Technologie-Stacks in verschiedenen Anwendungsteilen einzusetzen, bringt also nichts, wenn das Team so klein ist, dass man keine entsprechenden Experten hat.
