Suchen und Finden
Mehr zum Inhalt
Software modular bauen - Architektur von langlebigen Softwaresystemen - Grundlagen und Anwendung mit OSGi und Java
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
Alle Preise verstehen sich inklusive der gesetzlichen MwSt.