Inhaltsverzeichnis | 7 |
1 Einleitung | 11 |
1.1 Über dieses Buch | 12 |
1.1.1 Zielgruppe | 12 |
1.1.2 Aufbau | 13 |
1.1.3 Herangehensweise | 14 |
1.2 Motivation | 14 |
1.3 Nachstellen der Beispiele | 16 |
1.3.1 Voraussetzungen | 16 |
1.3.2 Synchronisieren von Projekten | 17 |
1.3.3 Ausführen der Projekte | 18 |
1.4 Regeln | 18 |
2 Grundlagen | 21 |
2.1 Definitionen | 21 |
2.2 Grundthese | 22 |
2.2.1 Komponenten und Module | 23 |
2.2.2 Selbstähnlichkeit von Architektur | 23 |
2.2.3 Schnittstelle und Implementierung | 25 |
2.3 Prinzipien und Konzepte | 26 |
2.4 Modularity Patterns | 31 |
2.4.1 Modularity Patterns in der Coding-Architektur | 31 |
2.4.2 Modularity Patterns in der Komponentenarchitektur | 32 |
2.4.3 Modularity Patterns in der Systemarchitektur | 33 |
2.5 Vorgehen zur Definition modularer Architektur | 35 |
2.5.1 Anforderungsanalyse | 35 |
2.5.2 Sichten | 36 |
2.5.3 Vorgehensmodelle während der Entwicklung | 37 |
2.6 Modularitätsmodell (Modularity Maturity Model) | 39 |
3 Coding-Architektur: Erweiterbarkeit | 43 |
3.1 Hintergrund von Coding Best Practices | 43 |
3.1.1 Design Patterns | 44 |
3.1.2 SOLID | 45 |
3.1.3 Modularity Patterns in diesem Kapitel | 46 |
3.2 Beschreibung des Anwendungsbeispiels | 46 |
3.3 Factory Pattern | 50 |
3.3.1 Umsetzung im Beispiel | 52 |
3.4 Decision Map | 55 |
3.4.1 Umsetzung im Beispiel | 55 |
3.4.2 Cyclomatic Complexity | 57 |
3.5 Single Responsibility | 59 |
3.5.1 Umsetzung im Beispiel | 60 |
3.6 Nachstellen des Beispiels | 61 |
3.7 Exkurs: Adapter und Facade | 61 |
3.7.1 Facade in Coding | 62 |
3.7.2 Traditionelle Adapter | 63 |
3.7.3 Modulare Adapter im Coding | 64 |
3.7.4 Nachstellen des Beispiels | 67 |
3.8 Zusammenfassung | 67 |
4 Komponentenarchitektur: Grundlagen | 69 |
4.1 Hintergrund eines modularen Laufzeitsystems | 69 |
4.1.1 Module | 69 |
4.1.2 Services zur Kommunikation | 71 |
4.1.3 Zusammenspiel von Modulen und Services | 73 |
4.1.4 Kohäsion | 73 |
4.1.5 Modulare Laufzeitsysteme im Vergleich | 77 |
4.1.6 Modularity Patterns in diesem Kapitel | 81 |
4.2 Umsetzung der Grundkonzepte am Beispiel OSGi | 81 |
4.2.1 Moduldefinition | 82 |
4.2.2 Sichtbarkeit von Klassen | 83 |
4.2.3 Services | 87 |
4.2.4 Versionierung von Bundles | 89 |
4.3 Auswirkungen eines modularen Laufzeitsystems auf Patterns | 90 |
4.3.1 Facade | 91 |
4.3.2 Adapter | 93 |
4.4 Umsetzung von Modularität in verschiedenen Laufzeitumgebungen | 95 |
4.4.1 Eingebettete OSGi-Container | 96 |
4.4.2 Eigenständiger OSGi-Container | 98 |
4.4.3 Vergleich | 99 |
4.5 Modularisierung durch Refactoring | 99 |
4.5.1 Kohäsion am Refactoring-Beispiel | 104 |
4.6 Zusammenfassung | 106 |
5 Komponentenarchitektur: Entkopplung | 109 |
5.1 Hintergrund modularisierter Software | 109 |
5.1.1 Schnittstelle von Modulen | 109 |
5.1.2 Dependency Injection | 110 |
5.1.3 Modularität ohne Schnittstellen | 112 |
5.1.4 Modularity Patterns in diesem Kapitel | 114 |
5.2 Grundlagen von Declarative Services | 114 |
5.2.1 Declarative Services als Dependency-Injection-Framework | 116 |
5.3 Entkopplung in der Beispielanwendung | 116 |
5.3.1 Entkopplung der Datenquellen | 119 |
5.3.2 Nachstellen des Beispiels | 122 |
5.3.3 Laufzeitdynamik von Datenquellen | 122 |
5.4 Exkurs: Zwei weitere SOLID-Prinzipien | 125 |
5.4.1 Single-Responsibility-Prinzip für Module | 126 |
5.4.2 Open-Closed-Prinzip für Module | 126 |
5.5 Hierarchien in der Beispielanwendung | 129 |
5.6 Schnittstellen in Modulen | 131 |
5.7 Zusammenfassung | 132 |
6 Systemarchitektur: Schichten | 135 |
6.1 Hintergrund von Schichten in der Architektur | 135 |
6.1.1 Schichtenarchitektur | 136 |
6.1.2 Schichten in den Ebenen der Architektur | 137 |
6.1.3 Modularity Patterns in diesem Kapitel | 138 |
6.2 Entkoppelte Komponenten in der Beispielanwendung | 138 |
6.2.1 Arbeit mit der OSGi Service Registry | 143 |
6.2.2 Nachstellen des Beispiels | 144 |
6.3 Gruppierung von Bundles | 144 |
6.3.1 Eclipse Feature | 145 |
6.3.2 Application im Apache-Aries-Projekt | 145 |
6.3.3 OSGi-Subsystem-Spezifikation | 146 |
6.3.4 Vergleich | 146 |
6.4 Schichtenarchitektur mit OSGi | 147 |
6.4.1 Arten der Abhängigkeiten zwischen Schichten | 149 |
6.4.2 Schichten in der Beispielanwendung | 152 |
6.4.3 Data Transfer Objects (DTO) in den Schichten | 154 |
6.4.4 Testen der einzelnen Schichten | 155 |
6.5 Exkurs: Testbarkeit | 158 |
6.5.1 Prinzip: Dependency Injection | 159 |
6.5.2 Prinzip: Vermeidung von globalem Zustand | 160 |
6.5.3 Prinzip: Law of Demeter | 161 |
6.6 Zusammenfassung | 162 |
7 Systemarchitektur: Erweiterbarkeit | 163 |
7.1 Hintergrund von Schnittstellen | 163 |
7.1.1 Schnittstellendesign | 164 |
7.1.2 Ersetzbarkeit | 169 |
7.1.3 Modularity Patterns in diesem Kapitel | 169 |
7.2 Schnittstellen in der Beispielanwendung | 170 |
7.2.1 Beispiel des API-Designs | 172 |
7.2.2 Anwendung auf OSGi | 174 |
7.3 Erweiterung der Schnittstellen | 176 |
7.3.1 Abstrakte Klassen | 177 |
7.3.2 Data Transfer Object (DTO) | 179 |
7.3.3 Schnittstellenevolution | 180 |
7.3.4 Unterschiede zwischen API- und SPI-Evolution | 182 |
7.4 Erweiterbarkeit mit OSGi | 182 |
7.4.1 Design von Schnittstellen in Modulen | 183 |
7.5 Ersetzbarkeit von Implementierungen | 184 |
7.6 Kohäsion in der Beispielanwendung | 186 |
7.7 Zusammenfassung | 188 |
8 Systemarchitektur: Wiederverwendbarkeit entkoppelter Komponenten | 191 |
8.1 Hintergrund entkoppelter wiederverwendbarer Komponenten | 191 |
8.1.1 Abhängigkeiten zu externen Komponenten | 192 |
8.1.2 Gemeinsam genutzte Aspekte | 192 |
8.1.3 Modularity Patterns in diesem Kapitel | 196 |
8.2 Entkopplung von externen Abhängigkeiten | 196 |
8.2.1 Ein Adapter für eine externe Komponente in der Beispielanwendung | 198 |
8.2.2 Weiterentwicklung mit externen Komponenten | 201 |
8.2.3 Nachstellen des Beispiels | 202 |
8.3 Gemeinsam genutzte Aspekte | 203 |
8.3.1 Validierung | 204 |
8.3.2 Transaktionen | 206 |
8.4 Zusammenfassung | 207 |
9 Systemarchitektur: Funktionale Entkopplung | 209 |
9.1 Hintergrund funktionaler Entkopplung | 209 |
9.1.1 Parallele Verarbeitung im System | 210 |
9.1.2 Versionierung von Modulen | 216 |
9.1.3 Modularity Patterns in diesem Kapitel | 218 |
9.2 Parallele Verarbeitung in der Beispielanwendung | 218 |
9.2.1 Nachrichtenbasierte Verarbeitung | 219 |
9.2.2 Nachstellen des Beispiels | 224 |
9.2.3 Exkurs: Weitere Konzepte der parallelen Verarbeitung | 225 |
9.3 Versionierung in der Beispielanwendung | 229 |
9.3.1 Neue Implementierungen | 230 |
9.3.2 Änderungen an einer Schnittstelle | 232 |
9.3.3 Umsetzung im Projekt | 238 |
9.3.4 Vorteile der Versionierung | 241 |
9.3.5 Nachstellen des Beispiels | 241 |
9.4 Zusammmenfassung | 242 |
10 Komponentenarchitektur: Frameworks | 243 |
10.1 Hintergrund der Frameworks | 244 |
10.1.1 Geschichte der Frameworks | 244 |
10.1.2 Frameworks für Dependency Injection | 246 |
10.1.3 Java EE | 247 |
10.1.4 Maven | 249 |
10.1.5 Vergleich der Frameworks bezüglich Modularität | 250 |
10.2 Umsetzung der Beispielanwendung mit CDI | 257 |
10.2.1 Struktur der Beispielanwendung | 258 |
10.2.2 Anpassungen an Weld | 258 |
10.3 Umsetzung der Beispielanwendung mit Spring | 263 |
10.3.1 Struktur der Beispielanwendung mit Spring | 263 |
10.4 Umsetzung der Beispielanwendung mit Maven | 267 |
10.5 Nachstellen des Beispiels | 268 |
10.6 Exkurs: Verwendung von OSGi | 269 |
10.6.1 Eclipse | 269 |
10.6.2 JBoss Application Server | 269 |
10.6.3 GlassFish | 269 |
10.6.4 IBM WebSphere | 270 |
10.7 Zusammenfassung | 270 |
11 Systemarchitektur: Product Line Engineering | 273 |
11.1 Hintergrund zu Product Line Engineering | 273 |
11.1.1 Domänen- und Anwendungsentwicklung | 274 |
11.1.2 Variabilität | 275 |
11.1.3 Variabilität und Schnittstellen | 276 |
11.2 Anwendung von PLE auf die Beispielanwendung | 276 |
11.2.1 OSGi und PLE | 278 |
11.2.2 Core Assets in OSGi | 279 |
11.2.3 Variabilität in OSGi – Extension Point | 280 |
11.2.4 Variabilität in OSGi – Konfiguration | 282 |
11.2.5 Variabilität in OSGi – DSL | 283 |
11.3 Mehrere Produkte | 283 |
11.4 Nachstellen des Beispiels | 286 |
11.5 Zusammenfassung | 287 |
12 Systemarchitektur: Repository | 289 |
12.1 Hintergrund von Repositories | 289 |
12.1.1 Anwendungsfälle für ein Repository | 290 |
12.1.2 Modularity Patterns in diesem Kapitel | 291 |
12.2 Ein Repository für OSGi | 291 |
12.2.1 Verwendung von p2 in Eclipse | 292 |
12.3 Das p2-Repository für die Beispielanwendung | 294 |
12.3.1 Abhängigkeiten zwischen Features | 295 |
12.3.2 Eclipse-Support für Update-Site und Features | 297 |
12.4 Verschiedene Einsatzmöglichkeiten | 298 |
12.4.1 Verwendung von p2 per API | 299 |
12.5 Maven-Repository | 301 |
12.6 Zusammenfassung | 302 |
13 Schlusswort | 305 |
13.1 Zusammenfassung | 305 |
13.1.1 Anwendung der Modularitätsstufen | 306 |
13.1.2 Einordnung von OSGi bezüglich Produktivität | 308 |
13.2 Ausblick | 309 |
A Appendix A: Tools zur Architekturvalidierung | 311 |
A.1 Korrektheit | 311 |
A.1.1 FindBugs | 312 |
A.1.2 PMD | 312 |
A.2 Metriken | 312 |
A.2.1 Eclipse Metrics | 313 |
A.3 Redundanz | 313 |
A.3.1 CPD | 313 |
B Appendix B: Projekt Jigsaw | 315 |
B.1 Designprinzipien | 315 |
B.2 Definitionen | 316 |
B.2.1 Modul | 316 |
B.2.2 Auflösung | 316 |
B.2.3 Phasen | 316 |
B.3 Moduldeklaration | 316 |
B.3.1 Exports | 317 |
B.3.2 Abhängigkeiten | 318 |
B.3.3 Services | 318 |
B.4 Vergleich mit OSGi | 319 |
C Appendix C: OSGi in der Praxis | 321 |
C.1 Lifecycle von Bundles | 321 |
C.2 Statusinformationen eines OSGi-Laufzeitsystems | 323 |
Referenzen | 325 |
Index | 329 |
A | 329 |
B | 329 |
C | 329 |
D | 329 |
E | 329 |
F | 329 |
G | 330 |
I | 330 |
J | 330 |
K | 330 |
L | 330 |
M | 330 |
N | 330 |
O | 330 |
P | 330 |
R | 331 |
S | 331 |
T | 331 |
V | 331 |
www.dpunkt.de | 0 |