# Design Patterns
- Typische Lösung für häufige Probleme im Software Design
  - Kein Code, nur Lösungsansatz
- Gute OO-Designs sind wiederverwendbar, erweiterbar, wartbar

## Pattern - SOLID

|                                                                 | Factory                                                       | Singleton | Composite                 | Adapter                        | Facade                      | Observer | Strategy | State |
|-----------------------------------------------------------------|---------------------------------------------------------------|-----------|---------------------------|--------------------------------|-----------------------------|----------|----------|-------|
| [Srp](SOLID-Principle.md#s-single-responsibility-principle-srp) | X <br/>viele unterschiedliche Creator, die eine Aufgabe haben | -         | ? <br/>(sowohl als auch)  | x                              | X<br/>mit Tendenz zu ?      | X        |          |       |
| [Ocp](SOLID-Principle.md#o-open-closed-principle-ocp)           | X                                                             | -         | X                         | x                              | - <br/>zumindest in Vorlage | X        |          |       |
| [Lsp](SOLID-Principle.md#l-liskov-s-substitution-principle-lsp) | ?                                                             | -         | ? <br/>(kann, muss nicht) | -                              | -                           | X        |          |       |
| [Isp](SOLID-Principle.md#i-interface-segregation-principle-isp) | ?/X                                                           | -         | -                         | X<br/>sollte, kann aber auch ? | - <br/>zumindest in Vorlage | X        |          |       |
| [Dip](SOLID-Principle.md#d-dependency-inversion-principle-dip)  | X                                                             | -         | X                         | X                              | - <br/>zumindest in Vorlage | ?        |          |       |

### Legend
- **X**: follows clearly
- **?**: not sure, might follow / changes with implementation
- **-**: has nothing to do with it

## Typen von Design Patterns
- **Creational Patterns**
  - Objekterstellungsmechanismen → erhöhen Flexibilität
- **Strukturelle Pattern**
  - Objekte anwenden und Klassen in größeren Strukturen gruppieren ohne Flexibilität einzubußen
- **Behavioral Patterns**
  - Algorithmen und Zuordnung von Verantwortlichkeiten

## How to use a design pattern
- Bibliotheken

## Observer Pattern
- One-To-Many Abhängigkeit
  - Wenn ein Objekt sich ändert
  - Alle Abhängigkeiten werden benachrichtigt

### Nutzung Observer Pattern
- Wenn Zustandsänderung eines Objekts Änderung in anderen Objekten hervorruft
- Wenn Objekte etwas beobachten müssen für eine bestimmte Zeit/Fall

### Beispiel Observer Pattern
- Kunden über Verfügbarkeit von Produkten informieren
  - 2 Typen von Objekten: Kunde, Markt

#### Pull
- Kunde fragt häufiger nach, ob es da ist
  - Meistens: NEIN

#### Push
- Markt schreibt alle Kunden an, sobald ein Produkt verfügbar ist
  - Auch die, die kein Interesse haben

#### Observer
- Jedes Produkt hat eine Liste von Subscribern
  - Sobald sich Verfügbarkeit ändert alle benachrichtigen

### Struktur Observer Pattern
![image_375.png](image_375.png)
#### Subject (Interface)
- Kennt seine Beobachter

#### Observer (Interface)
- Definiert Interface für Objekte, welche benachrichtigt werden sollen

#### ConcreteSubject
- Speichert Daten (oder Zustand) der Interesse
- Sendet Benachrichtigung bei Änderung 

#### Concrete Observer
- Behält Referenz zu ConcreteSubject
- Gespeicherter Zustand bleibt gleich mit Subject-Zustand
  - Implementiert das update-Interface des Observers

### Fazit Observer Pattern
- Wird gefördert durch das [OPC](SOLID-Principle.md#o-open-closed-principle-ocp)
- [LSP](SOLID-Principle.md#l-liskov-s-substitution-principle-lsp) wird angewendet
- [DIP](SOLID-Principle.md#d-dependency-inversion-principle-dip) wird angewendet
- [ISP](SOLID-Principle.md#i-interface-segregation-principle-isp) wird manchmal angewendet
  - Manchmal kann eine Klasse Observer und Subjekt sein


## Factory Method (Virtual Constructor)
- Interface für die Erstellung eines Objekts
  - Lässt Subklassen entscheiden welche Klassen instanziiert wird
- Ersteller Klassen wissen nicht von den tatsächlichen Objekten

### Struktur Factory Method
![image_376.png](image_376.png)
#### Product (Abstract Class / Interface)
- Definiert üblichen Typ der Objekte
- Abstraktion, welche von der restlichen Codebase genutzt wird

#### Concrete Product(s)
- Implementierung des Produkt-Interface

#### Creator (Abstract Class)
- Deklariert Factory-Methode
  - Gibt Objekt zurück
- Kann noch andere Methoden enthalten

#### ConcreteCreator
- Jedes semantische Produkt hat seinen eigenen ConcreteCreator
  - Überschreiben der Factory-Methode
  - Implementierung der Kreation der spezifischen Produkte
- Mehrere ConcreteCreator können ein ConcreteProduct erstellen (bspw. verschiedene Werte)

### Beispiel Factory Pattern
- **Logistik Management Anwendung**
- Erste Version kann nur mit LKWs transportieren
- Transportation mit Schiff kommt dazu
  - Code aus LKW Klasse muss teilweise auch in Schiffklasse verwendet werden
  - Vllt. kommen ja noch mehr Transportmittel dazu?
- **Lösung**
  - ![image_377.png](image_377.png)
  - Objektkreation macht nur die Factory-Methode, spezifisch für das Produkt
    - In diesem Fall Transport
  - Logistics ist der Ersteller
    - Plan für die Lieferung
    - Definierung der FactoryMethode
  - ConcreteCreators
    - ![image_378.png](image_378.png)

### Fazit Factory Method
- Implementierung von OO Prinzipien
  - [OCP](SOLID-Principle.md#o-open-closed-principle-ocp)
    - Motivierung ist, dass Applikation erweiterbar ist
    - Client bleibt geschlossen
  - [LSP](SOLID-Principle.md#l-liskov-s-substitution-principle-lsp)
    - Kann gestört werden durch unterdrückung der Standardimplementierung durch eine Subklasse
  - [DIP](SOLID-Principle.md#d-dependency-inversion-principle-dip)
    - Client definiert/besitzt Interface für Ersteller und Produkte
- Bestärkt [Loose Coupling](ImplementingForMaintainability.md#loose-coupling)


## Abstract Factory
- Interface für die Erstellung von Familien oder Abhängigkeiten von Objekten

### Struktur Abstract Factory
![image_379.png](image_379.png)
#### AbstractFactory (Interface)
- Deklariert Interface fpr Operationen, die Objekte produzieren

#### ConcreteFactory
- Repräsentiert Factory für eine Variante/Familie von Produkten
- Implementiert die Operationen, um Objekte zu erstellen

#### AbstractProduct (Interface)
- Deklariert Interface für einen Typ

#### ConcreteProduct
- Definiert konkretes Produkt der Familie

#### Client
- Nutzt nur AbstractFactory und AbstractProduct

### Beispiel Abstract Factory
- ![image_380.png](image_380.png)
- AbstractProduct
  - Chair, Sofa, CoffeeTable
- Produkt
  - 3 jeder abstrakten Klasse
- Abstract Factory
  - Interface für FurnitureFactory
- ConcreteFactory
  - Implementierung des AbstractFactory Interface

### Fazit Abstract Factory
- **OO Prinzipien**
  - [OCP](SOLID-Principle.md#o-open-closed-principle-ocp)
  - [LSP](SOLID-Principle.md#l-liskov-s-substitution-principle-lsp)
    - Abhängig von der Implementierung
  - [DIP](SOLID-Principle.md#d-dependency-inversion-principle-dip)
    - Client definiert/besitzt Interface für Ersteller und Produkte


## Singleton 
- Sorgt dafür, dass eine Klasse nur ein Interface hat und dieses global erreichbar ist
- Wird genutzt, wenn eine Klasse nur eine einzelne Instanz haben soll
  - bspw. DatenbankVerbindung

### Struktur Singleton
- Konstruktor hat private Sichtbarkeit
  - Methode getInstance()
    - ![image_381.png](image_381.png)

### Beispiel Singleton
- ![image_382.png](image_382.png)

### Fazit Singleton
- **Probleme**
  - Pattern löst zwei Probleme gleichzeitig 
    - verletzt [SRP](SOLID-Principle.md#s-single-responsibility-principle-srp)
  - Kann sychlechtes Design verstecken (bspw. kein Loose Coupling)


## Adapter Pattern
- Erlaubt das Nutzen eines Clients mit einem inkompatiblen Interface

### Structure Adapter Pattern
![image_401.png](image_401.png)
#### Target
- Definiert domänenspezifisches Interface, das der Client nutzt

#### Client (Adapter Pattern)
- Arbeitet mit Objekten, welche mit dem [Target](#target)-Interace übereinstimmen

#### Adaptee
- Definiert existierendes Interface, welches Adaption benötigt

#### Adapter
- Adaptiert das Interface des Adaptee zum Target-Interface

#### Collaborations
- Client ruft Operationen auf dem Adapter-Interface auf

### Beispiel Adapter Pattern
![image_402.png](image_402.png)
![image_403.png](image_403.png)

### Fazit Adapter Pattern
- **SRP**
  - Primäre Business Logik eines Programms ist vom Interface getrennt
- **OCP**
  - Neuer Adapter kann, ohne den existierenden Code zu bearbeiten, erstellt werden

- Adapter ändert Interface in eins, das der Client erwartet
- **Sollte vermieden werden, wenn es möglich ist**


## Facade Pattern
- Klasse, die ein simples Interface zu einem komplexen System bereitstellt

### Struture Facade Pattern
![image_404.png](image_404.png)
#### Facade
- Weiß, welche Subsystem-Klassen verantwortlich sind
- Delegiert Client-Anfragen an Klassen

#### Subsystem Classes
- Implementiert Subsystem Funktionalität
- Hat kein Wissen von der Fassade

#### Collaborations Facade Pattern
- Clients kommunizieren mit dem Subsystem durch requests zur Fassade

### Fazit Facade Pattern
- **SRP**
  - Kann verletzt werden je nach Implementierung

## Composite Pattern
- Baumartige Objektstruktur
### Structure Composite Pattern
![image_405.png](image_405.png)

#### Component (Abstract Class)
- Deklariert Interface für Objekte in der Komposition
- Implementiert für teilweises default-Verhalten

#### Leaf
- Definiert Verhalten, welches individuell für die Klasse ist

#### Composite
- Definiert Verhalten für Branch-Komponenten

#### Client (Composite Pattern)
- Nutzt Objekte in der Komposition durch das Interface

### Beispiel Composite Pattern
![image_406.png](image_406.png)
![image_407.png](image_407.png)

## Strategy Pattern
![image_408.png](image_408.png)

## State Pattern
![image_409.png](image_409.png)

