105 lines
9.1 KiB
TeX
105 lines
9.1 KiB
TeX
|
\section{Entwurfsmuster und Techniken}
|
||
|
|
||
|
\subsection{Entwurfsmuster}
|
||
|
|
||
|
\subsubsection{Dependency Injection}
|
||
|
|
||
|
Die Dependency Injection (dt. Abhängigkeitsinjektion) ist ein Entwurfsmuster, welches die Abhängigkeiten von Objekten bestimmt und an einem zentralen Ort speichert sowie verwaltet.
|
||
|
Sollte ein Objekt also von einem anderen Objekt abhängig sein, so wird an diesem zentralen Ort nach der Abhängigkeit gesucht.
|
||
|
Ist die Abhängigkeit vorhanden, so wird dieses Objekt dann an dem benötigten Ort eingesetzt (injiziert).
|
||
|
Dies geschieht während der Laufzeit.
|
||
|
Der zentrale Ort, an dem die Abhängigkeiten gespeichert werden, wird meist von einem Framework verwaltet.
|
||
|
|
||
|
Im Falle dieses Projekts ist \Gls{spring} das Framework und der \Gls{spring} Container der zentrale Ort, an dem die Abhängigkeiten gespeichert werden.
|
||
|
Der Vorteil dieses Entwurfsmusters ist, dass Objekte von anderen Objekten abgekoppelt werden, sprich: Das Objekt mit der Abhängigkeit muss nicht mehr von der expliziten Klasse Kenntnis haben und es kann nur mit Interfaces gearbeitet werden, was in den \Gls{solid}-Kriterien das D für Dependency Inversion erfüllt.
|
||
|
Ein weiterer Vorteil ist, dass die Abhängigkeiten innerhalb einer Konfigurationsdatei definiert werden können.
|
||
|
Sprich: Man kann mehrere Implementierungen besitzen, die alle das gleiche Interface implementieren und kann in der Konfigurationsdatei angeben, welche Implementierung gewählt werden soll.
|
||
|
|
||
|
\subsubsection{Data Access Object (DAO)}
|
||
|
\label{DAO_Pattern}
|
||
|
|
||
|
Das Data Access Object (kurz: DAO, dt: Datenzugriffsobjekt) ist ein Entwurfsmuster, das eingesetzt wird um den Zugriff auf \Gls{db}en zu vereinfachen und die \Gls{business} von der Datenzugriffslogik zu trennen.
|
||
|
Dazu gibt es zwei Komponenten: das DAO-Interface und die DAO-Implementierung.
|
||
|
|
||
|
Das DAO-Interface wird von allen DAO-Implementierungen implementiert und bietet alle Datenzugriffsfunktionen an, auf die die \Gls{business} zugreift.
|
||
|
Die DAO-Implementierung ist eine Klasse, die das DAO-Interface implementiert und den tatsächlichen Zugriff auf die \Gls{db} ausführt.
|
||
|
|
||
|
Der Vorteil dieses Entwurfsmusters ist es mehrere Implementierungen desselben DAO-Interfaces zu besitzen.
|
||
|
In Kombination mit der Dependency Injection ist es einfach zwischen den Implementierungen für verschiedene \Gls{db}en (bspw. MariaDB und My\Gls{SQL}) zu wechseln.
|
||
|
Damit wird der Datenzugriff flexibler.
|
||
|
Im Falle dieses Projekts wird eine DAO-Implementierung für MariaDB verwendet.
|
||
|
|
||
|
Ein weiterer Vorteil ist die zuvor angesprochene Trennung der Geschäfts- und Datenzugriffslogik.
|
||
|
Da sich die \Gls{business} und Datenzugriffslogik mithilfe dieses Musters in verschiedenen Komponenten befinden, sind diese voneinander getrennt und es wird einfacher die jeweiligen Implementierungen zu testen.
|
||
|
Gleichzeitig verbessert sich damit die Wiederverwendbarkeit des Codes, da die DAO-Implementierungen in anderen Programmen, die mit demselben DAO-Interface arbeiten, eingesetzt werden können.
|
||
|
|
||
|
Damit erfüllt das DAO-Muster die Kriterien S und O der \Gls{solid}-Kriterien.
|
||
|
Das Single-Responsibility Prinzip wird erfüllt, da der Zugriff auf die \Gls{db} von der \Gls{business} getrennt wird und damit die DAO-Implementierung alleine für den Zugriff auf die \Gls{db} verantwortlich ist.
|
||
|
Das Open/Closed Prinzip wird erfüllt, da die DAO-Implementierung erweitert werden kann, ohne dass der Rest vom Projekt betroffen wird und außerhalb der Klasse nur mit dem DAO-Interface gearbeitet werden kann.
|
||
|
|
||
|
\subsection{Techniken}
|
||
|
|
||
|
\subsubsection{JSON Web Token}
|
||
|
|
||
|
\Gls{json} Web Token (JWT) ist ein offener Standard der in RFC 7519 definiert wird.
|
||
|
Mit einem JWT ist es möglich Informationen sicher in einem kodierten \Gls{json} Objekt zu übertragen.
|
||
|
Die Sicherheit der Daten wird dabei durch eine digitale Signatur gewährleistet.
|
||
|
|
||
|
Ein JWT besteht aus drei durch Punkte ('.') voneinander getrennten Teilen:
|
||
|
\texttt{Header}, \texttt{Payload} und \texttt{Signatur}.
|
||
|
Der \texttt{Header} besteht dabei typischerweise aus der Information um welchen Typ von Token es sich handelt, also einen JWT,
|
||
|
und der Information welcher Signierungs-Algorithmus verwendet wird.
|
||
|
Diese Informationen werden \Gls{Base64} kodiert und bilden den ersten Teil des JWT.
|
||
|
|
||
|
Im \texttt{Payload} Teil werden die eigentlichen Informationen \Gls{Base64} kodiert.
|
||
|
|
||
|
Die \texttt{Signatur} ergibt sich durch die mit einem Punkt voneinander getrennten Kodierungen des \texttt{Headers} und
|
||
|
des \texttt{Payload}-Teils. Diese Zeichenkette wird dann mit einem geheimen Schlüssel
|
||
|
durch den im \texttt{Header} angegebenen Signierungs-Algorithmus signiert.
|
||
|
JWT werden einmalig vom Server erzeugt und beim Client gehalten. Daher ist es
|
||
|
nicht notwendig wie z.B. bei \gls{cookie} basierten Sessions, eine Liste mit gültigen Sessions auf dem Server zu verwalten, was bei mehreren Servern schwierig ist.
|
||
|
|
||
|
In diesem Projekt werden JWT zur Verifikation der E-Mail-Adresse eines Benutzers und zur Überprüfung der Autorisation bei Anfragen an den Server verwendet.
|
||
|
|
||
|
Zur Bestätigung der E-Mail-Adresse speichert der Server die zur Verifikation des
|
||
|
Benutzers benötigten Daten in einem JWT. Dieser wird in der URL des Verifikations-Links kodiert. Wenn der Benutzer den Verifikations-Link anklickt,
|
||
|
wird der JWT an den Server weitergeleitet. Dieser überprüft die Signatur des JWT ihn mit seinem geheimen Schlüssel
|
||
|
und kann so die Verifikation der E-Mail-Adresse abschließen.
|
||
|
|
||
|
Bei dem Login-Vorgang sendet der Client zuerst seine Anmeldedaten (Benutername und Passwort), um sich zu authentifizieren.
|
||
|
Der Server überprüft die Angaben, generiert einen JWT und gibt diesen zurück, falls die Daten korrekt sind.
|
||
|
Bei späteren Anfragen an den Server übermittelt der Client diesen JWT. Der Server überprüft die Validität des JWT und trifft
|
||
|
basierend darauf die Entscheidung, ob die Anfrage bearbeitet oder abgelehnt wird.
|
||
|
|
||
|
\subsubsection{Objektrelationale Abbildung (Object-relational mapping)}\label{t:orm}
|
||
|
|
||
|
Objektrelationale Abbildung - kurz ORM von der englischen Bezeichnung \enquote{Object-relational mapping} - ist eine Technik der Softwareentwicklung.
|
||
|
Sie widmet sich dem, mit der persistenten Speicherung von Laufzeit-Objekten zusammenhängenden \enquote{Impedance mismatch} Problem.
|
||
|
Dieses beschreibt die Diskrepanz zwischen den in der Pogrammier- beziehungsweise \Gls{db}welt vorherrschenden Konzepten - nämlich der objektorientierten Programmierung und relationalen \Gls{db}en.
|
||
|
So speichern objektorientierte Programmiersprachen Daten und Verhalten in Objekten mit eindeutiger Identität, wobei Zustand und Verhalten hinter einer Schnittstelle verborgen werden.
|
||
|
Relationale \Gls{db}en hingegen speichern Daten in Tabellen und basieren auf dem mathematischen Konzept der Relationenalgebra.
|
||
|
|
||
|
Objektrelationale Abbildung bietet eine Möglichkeit diese Diskrepanz zu vermindern, indem sie ein Mapping zwischen Objekten und Datenstrukturen relationaler \Gls{db}en herstellt.
|
||
|
Einem, in einer objektorientierten Programmiersprache geschriebenen, Anwendungsprogramm erscheint dann die verbundene relationale \Gls{db} als objektorientierte \Gls{db}.
|
||
|
Durch ORM wird also sowohl das Ablegen von Objekten mit Attributen und Methoden in relationale \Gls{db}en, als auch das Erzeugen von solchen Objekten aus entsprechenden Datensätzen ermöglicht.
|
||
|
Vorteilhaft ist daran außerdem, dass die objektorientierte Programmiersprache nicht erweitert werden muss.
|
||
|
Des Weiteren existiert für jede Umgebung ausgereifte Software für die Verwendung relationaler \Gls{db}en.
|
||
|
Allerdings ist der Schritt in Richtung objektorientiertem Ansatz immanent ein Schritt weg von den eigentlichen Stärken relationaler \Gls{db}en.
|
||
|
|
||
|
Der grundlegende Ansatz ist die Abbildung von Klassen auf Tabellen, wobei die Spalten den Attributen und die Zeilen den Objekten der Klasse zugeordnet sind.
|
||
|
Dabei entspricht der Primärschlüssel der Tabelle der Objektidentität und Objektreferenzen werden mithilfe von zusätzlichen Fremdschlüsseln repräsentiert.
|
||
|
%Um Vererbung abzubilden gibt es drei grundlegende Möglichkeiten.
|
||
|
%Erst einmal kann für eine Vererbungshierarchie auch genau eine gemeinsame Tabelle mit allen Attributen verwendet werden, in der ein Diskriminator bestimmt, zu welcher Klasse ein Objekt gehört.
|
||
|
%Als zweite Option kann pro Unterklasse eine zusätzliche verknüpfte Tabelle eingeführt werden.
|
||
|
%Letztlich kann auch pro konkreter Klasse eine Tabelle verwendet werden, wobei die Tabelle für die abstrakte Basisklasse entfällt.
|
||
|
|
||
|
Die von diesem Mapping betroffenen Klassen aus dem Model-Paket (\ref{p:model}) des Backends sind User, SubscriptionAction, Subscription, EpisodeAction und \Gls{episode}.
|
||
|
|
||
|
Konkret für dieses Projekt findet ORM als Technik durch die Implementierung der Jakarta Persistence \Gls{api} (JPA) Anwendung.
|
||
|
Dafür wird das von \Gls{spring} zur Implementierung von JPA-basierten Datenzugriffsschichten bereitgestellte Modul \Gls{spring} Data JPA genutzt.
|
||
|
Als JPA-Implementation wiederum wird das Open-Source-Persistenz- und ORM-Framework Hibernate für \Gls{java} verwendet.
|
||
|
Dabei erfolgen Abfragen der persistierten Objekte über die Abfragesprache Jakarta Persistence Query Language (JPQL), welche dann mittels JDBC in den entsprechen \Gls{SQL}-Dialekt für MariaDB übersetzt.
|
||
|
%Hier sei angemerkt, dass JPQL eine Untermenge der Hibernate Query Language (HQL) ist.
|
||
|
|
||
|
\newpage
|