-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgrundlagen.tex
More file actions
281 lines (241 loc) · 24.9 KB
/
grundlagen.tex
File metadata and controls
281 lines (241 loc) · 24.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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
170
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
206
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
% !TEX root = ../termpaper.tex
% Grundlagen
% @author Paul Höppner
%
\chapter{Grundlagen}
\section{Begriffsklärung} % (fold)
\label{sec:Begriffsklärung}
\subsection{Softwarearchitektur} % (fold)
\label{sub:Software_Architektur}
Softwarearchitektur ist ein sehr umfangreiches Gebiet und lässt sich schwer mit einer kurzen und prägnanten Definition beschreiben.
Len Bass und Rick Kazman haben folgende Definition vorgeschlagen~\cite{softArchInPractice}:
% LTeX: SETTINGS language=en-US
\glqq{}The software architecture of a program or computing system is the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them.\grqq{}.~\cite{softArchGrundl}\\
% LTeX: SETTINGS language=de-DE
\glq{}Software components\grq{} lassen sich hierbei als Software Bausteine übersetzen.
Mit Software Bausteinen sind die Teile, aus denen sich eine Software zusammensetzt, gemeint.
Hierbei können die Bausteine grob in drei Kategorien unterteilt werden~\cite{softArchGrundl}:
\begin{enumerate}
\item fachliche Bausteine
\item technische Bausteine
\item Plattform-Bausteine
\end{enumerate}
Dabei ist anzumerken, dass der Übergang zwischen den Kategorien fließend ist.\\
Fachliche Bausteine repräsentieren den Problembereich der Software und somit unter anderem die, an die Software gestellten, funktionalen Anforderungen.~\cite{softArchGrundl}\\
Auf fachlicher Ebene ist der Grad der Abstraktion sehr hoch und die Bausteine haben wenige Abhängigkeiten zur Plattform.
Unter der fachlichen Ebene liegt die technische Ebene, welche die nicht-funktionalen Anforderungen abdeckt.
Ein Beispiel für einen technischen Baustein ist die Datenbank als Persistenzlösung.
Im Vergleich zur fachlichen Ebene sinkt der Grad der Abstraktion der technischen Bausteine und die Abhängigkeit zur Plattform steigt.
Technische Bausteine können grobe fachliche Bausteine feiner unterteilen.
Vogel führt hier als Beispiel den fachlichen Baustein der Auftragsverwaltung an, der durch Verwendung des MVC-Musters (Näheres hierzu in Kapitel~\ref{sub:Model_View_Controller}), einer Art der technischen Architektur, in drei einzelne Bausteine, den Modell-, View- sowie Controller-Baustein aufgespalten wird.\\
\dots
\subsection{Minimal Viable Product} % (fold)
\label{sub:Minimal_Viable_Product}
% TODO: erste stelle der erwähnung finden
% TODO: pareto
Das Minimal Viable Product (Im Folgenden als MVP bezeichnet) bezeichnet die Iteration eines Produktes, welche so weit fortgeschritten ist, dass sie die minimalen Ansprüche des Kunden erfüllt~\cite{MVPOriginal}.
Es ist besonders nützlich um in einem frühen Stadium des Projektes Feedback von Kunden einzuholen.\\
% TODO: Zitat ordentlich einbinden
\glqq{}According to Lean Startup, every startup should start with building a Minimum viable product (MVP), and use it to validate their hypotheses about customer needs\grqq{}~\cite{MVPodrMFP}.\\
Es sind verschiedene Möglichkeiten der Umsetzung eines MVPs denkbar, wie zum Beispiel~\cite{MVPodrMFP}:
\begin{enumerate}
\item eine Landingpage, also eine Website, auf der ein Kunde landet, sobald die Website aufgerufen wird und das Design sowie einige Grundfunktionalitäten präsentieren kann
\item ein Mockup des Produktes, welches die Anwendung auf Papier oder einem ähnlichen Medium darstellt
\item ein \glqq{}Wizard of Oz\grqq{} MVP, bei dem der Kunde den Eindruck hat, als würde er ein fertiges Produkt bedienen, obwohl nur das Interface funktional ist, während die Logik händisch ausgeführt wird
\item ein Frontend MVP, bei dem die gesamte Logik des Produktes in dem Frontend ausgeführt wird und nur ein minimales bis kein Backend vorhanden ist
\end{enumerate}
Welche Art des MVP gewählt werden sollte, hängt hierbei stark von den Anforderungen an das Produkt ab.\\
Ein MVP hat viele Gemeinsamkeiten mit einem Prototyp, es handelt sich aber nicht um das gleich Konzept.
Anders als beim MVP ist der Prototyp nicht für den Endkunden, also im Fall einer Website den Anwender, sondern für den Auftraggeber gedacht, um die Kommunikation zwischen Auftraggeber und Entwickler zu vereinfachen.
Protoyping beschreibt sehr viel allgemeiner den Vorgang mithilfe eines Teilproduktes die Kommunikation zu vereinfachen.
Hierbei geht es auch um die Kommunikation innerhalb des Entwicklerteams.~\cite{floyd1984systematic}\\
Floyd beschreibt in ihrem Paper \glq{}A systematic look at Prototyping\grq{} die, in dieser Arbeit genauer betrachteten, Frontend Prototypen, den sie als \glqq{}Human Interface (Front End) Simulation\grqq{} bezeichnet.
Sie beschreibt hier einen Prototyp, der ein finales Frontend präsentiert, aber dessen andere Funktionalitäten, wie die Evaluierung der eingegebenen Daten, nicht vollständig, sondern nur als Mockup implementiert sind.~\cite{floyd1984systematic}
\section{Architekturprinzipien} % (fold)
\label{sec:Architektur_Prinzipien}
Um die Motivation hinter verschiedenen Architekturmustern zu verstehen, ist es notwendig einige grundlegende Prinzipien zu verstehen.
Die dafür wichtigsten sind in diesem Kapitel aufgeführt.
\subsection{Prinzip der losen Kopplung und hohen Kohäsion} % (fold)
\label{sub:Prinzip_der_loosen_Kopplung_und_hohen_Kohäsion}
Unter der Kopplung eines Systems versteht man die Abhängigkeiten von Systembausteinen untereinander.
Hierbei ist zwischen unterschiedlich starken Abhängigkeiten zu unterscheiden.
Greifen Klassen beispielsweise auf die privaten Daten einer anderen Klasse direkt zu, besitzen diese Klassen eine hohe Kopplung, da zur Änderung der einen Klasse Wissen über die internen Strukturen der anderen Klasse notwendig ist.
Ist der Datenzugriff im Gegensatz dazu über einen Methodenaufruf realisiert, spricht man zwar immer noch von einer Kopplung, diese ist aber wesentlich loser als in dem vorher genannten Beispiel, da keine Kenntnis der inneren Struktur der anderen Klasse notwendig ist.
In einem System ist einen lose Kopplung erstrebenswert, da dies die Wartung und Anpassung von Bausteinen erleichtert.~\cite{softArchGrundl}\\
Ein weiteres Prinzip, auf das in Zusammenhang mit loser Kopplung geachtet werden muss, ist das Vermeiden von zirkulären Abhängigkeiten.
Hierbei wäre Komponente A von Komponente B abhängig, welche dann wiederum von Komponente C abhängig ist.
Komponente C ist jedoch von Komponente A abhängig, wodurch eine zirkuläre Abhängigkeit entsteht (siehe Abb.~\ref{fig:../images/circ_depend.png}).
Diese zirkulären Abhängigkeiten sollten unbedingt vermieden werden, da sie zu einer hohen Kopplung führen.
Wird eine der Komponenten verändert, muss der gesamte Zyklus getestet und damit auch verstanden werden um Komponente A zu testen.
\includenamedimage[.7]{../images/circ_depend.png}{Darstellung zirkulärer Abhängigkeiten}
Mit einer losen Kopplung entsteht häufig eine hohe Kohäsion.
Kohäsion beschreibt hierbei die interne Abhängigkeit der Klasse beziehungsweise, wie gut die Klasse ihre spezifische Aufgabe erfüllt.
Es sollte also darauf geachtet werden, dass für eine Aufgabe nicht mehrere Klassen geschrieben werden, die dann wiederum einen hohe Kopplung besitzen, sondern die Funktionalität in einer Klasse gebündelt wird.~\cite{softArchGrundl}
\subsection{Separation of Concerns} % (fold)
\label{sub:Separation_of_Concerns}
Separation of Concerns, zu übersetzen als Trennung von Belangen, ist ein Prinzip, dass in der Softwareentwicklung in vielen Bereichen und nicht nur in der Softwarearchitektur verwendet wird.
Es beschreibt die Praxis Probleme in kleinere, weniger Komplexe, Teilbereiche aufzutrennen und folgt damit dem römischen Prinzip \glqq{}Teile und Herrsche\grqq{} (oft auch als \glqq{}Divide and Conquer\grqq{} bezeichnet).~\cite{softArchGrundl}\\
Das Prinzip lässt sich auf beliebig tiefen Abstraktionsebenen anwenden.
So ist sieht es vor, dass einzelne Module nur wenige Aufgaben haben, aber auch auf Klassen- und Methodenebene nur jeweils ein bestimmtes Belangen umgesetzt wird.~\cite{eilebrecht2018patterns}~\cite{softArchGrundl}\\
Wird das Prinzip gut umgesetzt, führt es zu einer losen Kopplung sowie einer hohen Kohäsion und einer einfacheren Wartung des Systems.
Auftretende Probleme können entsprechend geteilt und dann von mehreren Teams parallel gelöst werden.~\cite{softArchGrundl}
\subsection{Entwurf für Veränderung} % (fold)
\label{sub:Entwurf_für_Veraenderung}
Da sich Software in einem ständigen Wandel befindet, handelt es sich bei Anwendungen selten um statische Produkte.
Antizipiert man zukünftig nötige Veränderungen bereits während des Entwurfsprozesses spricht man vom sogenannten Entwurf für Veränderung (englisch: Design for Change).~\cite{softArchGrundl}\\
Das Prinzip ist sehr allgemeingültig und sagt im Grunde nur aus, dass die Architektur bestmöglich auf spätere Veränderungen vorbereitet sein sollte.
Dabei ist zwischen erwartbaren und nicht erwartbaren Änderungen zu unterscheiden.
Während erwartbare Änderungen explizit vorbereitet werden können, muss das System für nicht erwartbare Änderungen so entworfen werden, dass es generell erweiterbar ist.\\
Achtet man während des Entwurfs auf eine lose Kopplung ist der Entwurf für Veränderung häufig leichter umzusetzen.
Ein Nachteil dieses Prinzips ist, dass änderbare Architekturen häufig weniger performant als statische, weshalb immer zwischen Leistung und Änderbarkeit abgewogen werden muss.~\cite{softArchGrundl}
\subsection{Information-Hiding-Prinzip} % (fold)
\label{sub:Information-Hiding-Prinzip}
Für das Verstehen von Anwendungen können zu viele Informationen schnell kontraproduktiv sein.
Dieses Problem soll das Information-Hiding-Prinzip lösen.
Hierzu besagt es, dass Klienten nur die Informationen präsentiert bekommen, die unbedingt notwendig sind.
Alle restlichen Informationen werden vor dem Klienten verborgen.
Das Prinzip ist von großer Bedeutung hinsichtlich des Verständnisses von großen Anwendungen und sollte deswegen unbedingt beachtet werden.~\cite{softArchGrundl}\\
Eine Anwendung des Information-Hiding-Prinzips findet sich in der Modularisierung, da hier die Module nach außen nur durch Schnittstellen Informationen austauschen.
Sind keine Informationen über die inneren Strukturen bekannt, spricht man von sogenannten Black-Boxes.~\cite{softArchGrundl}\\
Durch Information-Hiding wird eine losere Kopplung erzwungen, da für eine hohe Kopplung Kenntnisse über innere Strukturen notwendig sind.
\section{Architekturstile} % (fold)
\label{sec:Übersicht_Architekturen}
Das Ziel der Arbeit ist nicht eine fertige Gesamtarchitektur zu erstellen, sondern einen Architekturstil vorzuschlagen.
Unter einem Architekturstil versteht man eine Menge von architektonischen Lösungen für Probleme, welche sich zu einer nicht vollständig spezifizierten Architektur zusammensetzt.
Der Stil beinhaltet Vorschläge für zu verwendende Patterns und Topologien der Komponenten.~\cite{softArchInPractice}
Verschiedenste Architekturmuster, an denen man sich während der Softwareentwicklung orientieren kann, sind über die Jahre entstanden.
Die wichtigsten davon sollen hier kurz beleuchtet werden, um einen guten Überblick zu schaffen.
\subsection{Monolith} % (fold)
\label{sub:Monolith}
Die als \glq{}Worst Case\grq{} geltende Architektur wird als Monolith bezeichnet.
Hierbei wird das gesamte System in einer Komponente realisiert, was dafür sorgt, dass keine Separation of Concerns geschieht.
Monolithen entstehen oft eher aus alten Systemen als dass sie aktiv geplant werden.
Eine lose Kopplung ist nicht zu erreichen, da keine gekoppelten Bausteine vorhanden sind, man kann deshalb weder von loser noch enger Kopplung sprechen.~\cite{softArchGrundl}\\
Monolithen sind häufig sehr schwer anzupassen und zu testen.
Meist gibt es nur wenige Entwickler, die das gesamte System ausreichend gut verstehen, um Änderungen umzusetzen, was dazu führt, dass monolithische Systeme schwer zu pflegen sind, wenn diese Entwickler das Unternehmen verlassen.
Generell sollte ein klassischer Monolith nicht das Ergebnis einer Architekturplanung sein.~\cite{softArchGrundl}
\subsection{Model View Controller} % (fold)
\label{sub:Model_View_Controller}
Das bereits erwähnte Model View Controller (MVC) Muster unterteilt die Verantwortlichkeiten bei Benutzerschnittstellen in drei Rollen.
Die drei Rollen sind das Model, welches für die Verwaltung der darzustellenden Daten verantwortlich ist, die View, die für die Darstellung sorgt und der Controller, welcher Benutzereingaben verwaltet und Daten ändert.
Der Controller sorgt außerdem für die Aktualisierung der View.\\
Vorteile des Musters sind unter anderem, dass die Benutzeroberfläche verändert werden kann, ohne dass das Model davon betroffen ist.
Dadurch ist dies sogar zur Laufzeit möglich.
Außerdem kann der Änderungsaufwand präziser eingeschätzt werden, da klar ist welche Teile betroffen sind.
Ein Nachteil ist, dass der Implementierungsaufwand höher ausfallen könnte, da Schnittstellen zwischen den Komponenten umgesetzt werden müssen.
Generell beruht das Model View Controller Muster auf dem Prinzip der Trennung der Verantwortlichkeiten.~\cite{eilebrecht2018patterns}
\subsection{Client-Server-Modell} % (fold)
\label{sub:Client_Server_Modell}
In Webanwendungen ist ein Client-Server-Modell heutzutage der etablierte Standard.
Hierbei wird auf einem Rechner eine Anwendung betrieben, der Client, welche auf zentral verwaltete Ressourcen, den Server, zugreift.
Dabei können mehrere Clients auf einen Server zugreifen, es können aber auch mehrere Server für verschiedene Ressourcen zur Verfügung stehen.
Der Hauptvorteil einer solchen Architektur ist, dass Anwendungen nicht als ganzes immer vollständig an den Anwender übertragen werden müssen, sondern nach und nach, mittels Anfragen an den Server, bereitgestellt werden.~\cite{softArchGrundl}\\
\includenamedimage[.8]{../images/ClientServer.png}{Informationsaustausch im Client-Server-Modell (Abbildung nach~\cite{softArchGrundl})}
Wie die Arbeit zwischen dem Client und dem Server aufgeteilt werden soll, bestimmt welche der, im Folgenden aufgeführten, Variation der Client-Server-Architektur verwendet werden sollte.
\subsubsection{Thin Client} % (fold)
\label{ssub:Thin Client}
Als Thin Client wird ein schlanker Client bezeichnet, der möglichst wenig Arbeit übernimmt.
Hier ist meist ein einfacher Webbrowser ausreichend, um die auf HTML, Javascript und CSS basierten Anwendungen auszuführen.~\cite{WebarchitekturenOnline}\\
Dadurch, dass der Server so gut wie alle Berechnungen übernimmt, müssen umso mehr Daten ausgetauscht werden, was das Netzwerk und den Server belastet.
Aus diesem Grund bieten sich Thin Client Anwendungen für Anwendungen in einer Umgebung mit stabiler Netzanbindung an.
\subsubsection{Rich Client} % (fold)
\label{ssub:Richt Client}
Ein Rich Client beinhaltet alle Funktionen des Thin Clients, kann aber eine dedizierte Benutzeroberfläche bieten~\cite{WebarchitekturenOnline} und auch Daten speichern~\cite{softArchGrundl}.
Werden Daten lokal gespeichert bietet dies den Vorteil, dass der Client nicht so abhängig von der Netzanbindung ist, diese Daten müssen aber eventuell synchronisiert werden, um aktuell gehalten zu werden.
Softwareupdates werden ebenfalls über das Netzwerk ausgeliefert.~\cite{softArchGrundl} % TODO: vllt noch bisschen was ergänzen
\subsubsection{Fat Client} % (fold)
\label{ssub:Fat Client}
Klassische Desktopanwendungen werden als Fat Client bezeichnet.
Auch diese können ihre Daten über Webservices von einem Server beziehen, werden aber lokal auf einem Rechner installiert.~\cite{WebarchitekturenOnline}\\
Fat Clients bieten sich an, um Server zu entlasten und wenn die Rechner, auf denen die Anwendung installiert wird, genug Leistung zur Verfügung stellt, um alle nötigen Berechnungen durchzuführen.
In den meisten Fällen haben Fat Clients wenig Abhängigkeiten vom Netzwerk und können häufig, wenn auch meist mit Einschränkungen der Funktionen, ohne Netzanbindung betrieben werden.
\subsection{Peer to Peer} % (fold)
\label{sub:Peer_to_Peer}
Als Gegenspieler des zentralisierten Client-Server-Modells existiert die Peer to Peer (auch häufig als P2P bezeichnet).
Hier kommunizieren die Klienten nicht über einen zentralen Server, sondern direkt untereinander, also dezentralisiert.
Die kommunizierenden Klienten werden als Peers bezeichnet und gleichwertig behandelt.
Dienste, die das System anbietet, und dessen Zustand sind zwischen den einzelnen Peers verteilt.~\cite{softArchGrundl}\\
Es kann ein zentraler Server verwendet werden, um neue Peers in das System einzupflegen.
In diesem Fall wird die Architektur als Hybrid zwischen P2P und dem Client-Server-Modell bezeichnet.~\cite{softArchGrundl}
\subsection{REST} % (fold) % TODO: Machen und einordnen
\label{sub:REST}
REST steht für \glq{}Representational State Transfer\grq{} und ist ein Architekturstil, der bezüglich der Übertragung von Daten, zwischen Anwendungen über das Netzwerk, Vorschläge enthält.
Dabei werden die Daten über die existierenden Web-Standards HTTP und URI übertragen. % TODO: HTTP und URI erklären?
Die Schnittstellen sind dabei HTTP-Requests an eine, je nach Schnittstelle definierte, URI.~\cite{softArchGrundl}\\
Ein Beispiel hierfür wäre eine GET-Anfrage an die URI:\\
\lstinline{www.api.haw-hamburg.de/studenten/2435451}\\
um den Studenten mit der Matrikelnummer 2435451 zurückzubekommen.
Diese Daten werden meist in einem XML oder JSON Format zurückgeliefert. % TODO: Quelle
% TODO: zustandslos
\subsection{Service Oriented Architecture} % (fold)
\label{sec:Service Oriented Architecture}
Die serviceorientierte Architektur (im Folgenden als SOA bezeichnet) ähnelt einem modularen Ansatz in vielen Teilen, erweitert diesen aber um komplexere Systeme realisieren zu können.
Bausteine werden hier als verteilte, lose gekoppelte Dienste (englisch: Services) realisiert.
Diese Dienste sind über, zum Beispiel auf Basis von REST, standardisierte Schnittstellen erreichbar und können so untereinander kommunizieren.\\
Um eine optimale Zusammenarbeit der Services zu gewährleisten ist es ideal, wenn diese idempotent, zustandslos sowie transaktional abgeschlossen.
Als idempotent werden Vorgänge bezeichnet, die immer zu dem gleichen Ergebnis führen, wenn sie mit der gleichen Eingabe durchgeführt werden, unabhängig davon wie oft sie ausgeführt werden.~\cite{softArchGrundl}
Transaktional abgeschlossene Vorgänge gehen von einem zulässigen Zustand wieder in einen zulässigen Zustand des Systems.
Ist kein zulässiger Zustand nach der Transaktion gegeben, wird diese rückgängig gemacht, um das System wieder in den Zustand vor der Transaktion zu überführen.
% TODO: Not done yet
% section section name (end)
\includenamedimage[.7]{../images/MVC.png}{Model View Controller (Abbildung nach~\cite{eilebrecht2018patterns})}
\subsection{Schichten Architektur} % (fold)
\label{sub:Schichten Architektur}
Im Allgemeinen versteht man unter einer Schichtenarchitektur eine Architektur, bei der die Software in diskrete Schichten aufgeteilt ist.
Diese Schichten können hierbei je nach Abstraktionsgrad als Funktionalitäten, Komponenten oder Klassen betrachtet werden.\\
Bei einer geschlossenen Schichtenarchitektur kommunizieren die Schichten nur mit der jeweils nächsten Schicht, was dafür sorgt, dass Schnittstellen zwischen den Schichten klar definiert und begrenzt sind.
Die Schichtenarchitektur setzt damit das Information-Hiding-Prinzip um.
Dies führt zu einer guten Wartbarkeit, da die Abhängigkeiten der einzelnen Schichten dadurch gering gehalten werden.~\cite{softArchGrundl}\\
Können Schichten übersprungen werden, spricht man von einer offenen Schichtenarchitektur.~\cite{buschmann2007pattern}\\
Dies kann dazu führen, dass die Anwendung eine bessere Performance aufweist, da Daten bei einer geschlossenen Schichtenarchitektur alle Schichten passieren müssen, die zwischen zwei Schichten liegen, auch wenn diese dort nicht verarbeitet werden müssen.
Des Weiteren führt die offene Architektur jedoch zu einer hohen Kopplung, da die einzelnen Schichten, im schlimmsten Fall, zu jeder anderen Schicht Abhängigkeiten besitzen.\\
Eine Schichtenarchitektur in einem Client-Server-Modell ist hilfreich, um hohe Lasten verarbeiten zu können.
Die Benutzeroberfläche läuft hier auf dem Rechner des Anwenders, während der Server auf mehrere Schichten und auch Rechner verteilt sein kann.
Dadurch kann die erste Serverschicht beispielsweise für die Lastverteilung auf die Server danach zuständig sein.
Die folgenden Server könnten dann auf einen, wieder als eigene Schicht realisierten, Datenbankserver zugreifen.
Durch eine solche Schichtenarchitektur lassen sich die einzelnen Schichten gut skalieren.~\cite{softArchGrundl}
\subsection{Domain Driven Design} % (fold)
\label{sub:Domain_Driven_Design}
\subsection{Microservices} % (fold)
\label{sub:Microservices}
Microservices bezeichnen einen Architekturstil, bei dem Funktionalitäten in voneinander getrennte, austauschbare Services aufgeteilt werden.
Das Ziel ist es hierbei einen leichte Ersetzbarkeit und damit einen bessere Wartbarkeit einzelner Bausteine zu gewährleisten.
Die Services werden meist von kleinen Teams entwickelt, was möglich ist, da die Kommunikation der Services über vorher definierte Schnittstellen realisiert wird und dadurch eine lose Kopplung erreicht wird.\\
Die Vorteile von Microservices überwiegen die Nachteile, die aber nicht unterschätzt werden sollten.~\cite{GrundlagenModular}\\
Im Folgenden werden zunächst einige Vorteile aufgelistet:
\begin{enumerate}
\item Es ist möglich in verschieden Services komplett unterschiedliche Technologien einzusetzen.
\item Durch die geringe Größe der einzelnen Services ist weniger Planung und Organisation nötig als bei einem monolithischen Projekt.
\item Nicht funktionale Anforderungen können pro Service einzeln und damit feingranularer definiert werden.
\item Treten Fehler auf, können diese meist schnell lokalisiert und damit auch schneller behoben werden und andere Services sind nur von dem Fehler betroffen, wenn sie Abhängigkeiten zu der fehlerhaften Komponente haben.
\end{enumerate}
Folgende Nachteile sollten bei dem Entwurf eines Microservices unbedingt bedacht werden:
\begin{enumerate}
\item Microservices sind als verteiltes System zu sehen und bringen damit viele Herausforderungen dieser Systeme mit sich. Die Fehlersuche wird dadurch erschwert, dass die Kommunikation über das Netzwerk stattfindet und somit schwerer zu verfolgen ist. Dies führt außerdem dazu, dass Aufrufe zwischen den Services durch externe Fehler, wie Paketverlust, schlechte Internetverbindungen oder Ähnlichem fehlschlagen.
\item Ändern sich Schnittstellen, müssen dies meist mehrere Teams umsetzen, was zu Fehlern führen kann.
\item Ein hohes Maß an Automatisierung ist nötig, um Microservices effizient zu testen und zu deployen.
\end{enumerate}
Generell sind mehrere Variationen der Realisierung von Microservices vorstellbar.
Im Folgenden sollen zwei grundlegende vorgestellt werden.
\subsubsection{Horizontale Microservices} % (fold)
\label{ssub:Horizontale_Microservices}
Bei Horizontalen Microservices setzt die UI auf einer Menge von Microservices auf und kommunizieren über eine API mit ihnen.
Diese Kommunikation wird üblicherweise von dem API-Gateway übernommen.
Untereinander kommunizieren die Services über die Service-Discovery-Komponente (siehe Abbildung~\ref{fig:../images/Horizontale_Microservices.png}).
Welche Aufgaben beide Komponenten jeweils übernehmen, ist nicht vorgeschrieben und kann sich von Implementierung zu Implementierung unterscheiden.
Horizontale Microservices bieten sich an, wenn mehrere UI-Komponenten, wie zum Beispiel eine App- und eine Webansicht, geplant sind.~\cite{GrundlagenModular}
\includenamedimage[.8]{../images/Horizontale_Microservices.png}{Horizontale Version von Microservices (Abbildung aus~\cite{GrundlagenModular})}
\subsubsection{Vertikale Microservices} % (fold)
\label{ssub:Vertikale_Microservices}
Im Gegensatz zu der horizontalen Variante werden bei der vertikalen Variante die UI-Komponenten mit in die jeweiligen Services aufgenommen.
Die Services werden dann nach jeweiligen Subdomänen klar getrennt (siehe Abbildung~\ref{fig:../images/Vertikale_Microservices.png}).
Durch diese Variante wird die Kopplung auf ein Minimum reduziert.
Es bietet sich an, die vertikale Variante immer zu verwenden, wenn nichts speziell für die Horizontale Variante spricht.~\cite{GrundlagenModular}
\includenamedimage[.8]{../images/Vertikale_Microservices.png}{Vertikale Version von Microservices (Abbildung aus~\cite{GrundlagenModular})}
\subsection{Hybride Architekturen aus Monolith und Microservices} % (fold)
\label{sub:Hybride_Architekturen_aus_Monolith_und_Microservices}
In großen Projekten können die Nachteile von Microservices ein großes Hindernis darstellen, weshalb eine Mischform von Monolithen und Microservices verwendet werden.
Hierbei werden einzelne Microservices zu Einheiten gebündelt, die dann wiederum einen eigenen Service darstellen.~\cite{softArchGrundl}\\
Man spricht auch von Macroservices~\cite{Macroser76:online}.
Es bietet sich vor allem an Hybride Architekturen zu verwenden, wenn ein monolithisches Softwareprodukt erweitert werden soll.
Der Monolith muss dann nur um eine Schnittstelle zu dem neuen Service erweitert werden.