Skip to content

Kapitel 6: Domain Driven Design

Julian Herzog edited this page Jun 7, 2024 · 11 revisions

Ubiquitous Language

Vier Beispiele für die Ubiquitous Language; jeweils Bezeichung, Bedeutung und kurze Begründung, warum es zur Ubiquitous Language gehört

Bezeichung Bedeutung Begründung
Category Eine Menge an Fragen, die sich mit dem selben Themengebiet befasst Auch im Vorbild des Spiels werden den Fragen Themengebiete zugeordnet und so Kategorien gebildet, die die Spieler abwechselnd wählen dürfen. Kategorien müssen daher auch Teil der Anwendung und der Ubiquitous Language sein.
Question Eine Frage aus einer bestimmten Kategorie mit verschiedenen Antwortoptionen Die Fragen gehören zu jedem Quiz-Spiel und sind somit ein essentieller Bestandteil sowohl der Domäne als auch der Ubiquitous Language.
QuestionOption Eine mögliche Antwort auf eine Frage, die falsch oder richtig sein kann Genauso wie die Fragen gehören die Antwortoptionen zu jedem Quiz-Spiel. Neben der Wahl der Kategorien ist die Entscheidung für eine Antwortoption die wichtigste Aufgabe des Spielers und damit Teil der Ubiquitous Language.
Player Ein Spieler, der ein Spiel spielt, Kategorien wählt, Fragen beantwortet und Punkte erhält Der Spieler ist die wichtigste Entität des Spiels und muss daher auch in der Anwendung modelliert werden. Er ist daher auch Teil der Ubiquituos Language.

Entities

UML, Beschreibung und Begründung des Einsatzes einer Entity; falls keine Entity vorhanden: ausführliche Begründung, warum es keines geben kann/hier nicht sinnvoll ist

Eine Entität des Spiels ist der Spieler. Ein Spieler ist ein bestimmter Benutzer des Spiel in einem konkreten Spiel. Der Lebenszyklus ist damit jeweils von Beginn bis Ende des entsprechenden Spiels definiert. Ein Spieler hat einen Namen und einen aktuellen Score. Die Identität des Spielers ist unabhängig von seinem Namen. Der Score des Spielers kann sich ändern, ohne dass der Spieler seine Identität verliert. Die Werte eines Spielers definieren also nicht seine Identität. Somit können zwei Spieler den gleichen Namen und den gleichen Score haben und sich dennoch in ihrer Identität unterscheiden.

classDiagram
direction BT
class Player {
  + Player(String) 
  - String playerName
  - Score currentScore
  + getCurrentScore() Score
  + getPlayerName() String
  + incrementScore(Score) void
}
Loading

Value Objects

UML, Beschreibung und Begründung des Einsatzes eines Value Objects; falls kein Value Object vorhanden: ausführliche Begründung, warum es keines geben kann/hier nicht sinnvoll ist

Als Value Object wurde der Score umgesetzt, da dieser ein Objekt ohne eigene Identität darstellt. Er wird durch seinen Wert definiert, ein Punkt unterscheidet sich nicht von einem anderen. Der Score ist unveränderlich und hat keinen Lebenszyklus. Er repräsentiert die Anzahl der von einen Spieler gesammelten Punkte zu einem bestimmten Zeitpunkt des Spiels. Der Score mehrerer Spieler kann zum Spielende verglichen werden, um einen Sieger zu ermitteln.

classDiagram
direction BT
class Score {
  + Score(int) 
  - int score
  + getIntScore() int
}
Loading

Repositories

UML, Beschreibung und Begründung des Einsatzes eines Repositories; falls kein Repository vorhanden: ausführliche Begründung, warum es keines geben kann/hier nicht sinnvoll ist

Es werden verschiedene Repositories eingesetzt, um die Speicherung zentral, aber getrennt nach verschiedenen Bereichen, zu verwalten. Es wird zwischen dem CategoryRepository, SettingsRepository und UserRepository unterschieden. Das CategoryRepository umfasst eine Liste aller verfügbaren Kategorien, die beim Starten der Anwendung aus einer JSON-Datei eingelesen wurden. Im SettingsRepository werden Spieleinstellungen, wie die Anzahl der Kategorien, die in einem Spiel pro Spieler gespielt werden, gespeichert. Das UserRepository beinhaltet eine Liste aller Benutzer und bietet Möglichkeiten zum Hinzufügen und Entfernen von Benutzern.

classDiagram
direction BT
class UserRepositoryImpl {
  + UserRepositoryImpl() 
  - List~User~ users
  + removeUser(User) void
  + addUser(User) void
  + getUsers() List~User~
}
Loading

Aggregates

UML, Beschreibung und Begründung des Einsatzes eines Aggregates; falls kein Aggregate vorhanden: ausführliche Begründung, warum es keines geben kann/hier nicht sinnvoll ist

Als Aggregat kann die Kombination aus Category, Question und QuestionOption betrachtet werden. Die Kategorie ist hierbei das Aggregat Root (AR), das den Zugriff auf die Fragen ermöglicht und damit die Objekte zu einer zentral verwalteten Einheit aggregiert. Es wird immer nur über eine Kategorie auf die Fragen zugegriffen. Es sind daher auch keine langfristigen Referenzen direkt auf eine Frage oder Antwortoption erlaubt. Durch diese Betrachtung als eine Einheit und die festgelegten Regeln zur Interaktion mit dieser wird die Komplexität der Beziehungen zwischen und zu diesen Objekten reduziert.

classDiagram
direction BT
class Category {
  + Category(int, String, Question[]) 
  - String categoryName
  - int id
  - Question[] questions
  + getRandomQuestion() Question
  + getDisplayName() String
  + getQuestions() Question[]
  + getId() int
  + getCategoryName() String
}
class Question {
  + Question(int, String, QuestionOption[]) 
  + Question(int, String, QuestionOption[], boolean) 
  - QuestionOption[] questionOptions
  - String question
  - int id
  + getId() int
  + getQuestionOptions() QuestionOption[]
  + getQuestion() String
  + checkAnswer(int) boolean
}
class QuestionOption {
  + QuestionOption(String, boolean) 
  - boolean isRight
  - String questionOption
  + getDisplayName() String
  + isRight() boolean
  + getQuestionOption() String
}

Category "1" *--> "questions *" Question 
Question "1" *--> "questionOptions *" QuestionOption 
Question  ..>  QuestionOption : «create»
Loading