# 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
viele unterschiedliche Creator, die eine Aufgabe haben | - | ?
(sowohl als auch) | x | X
mit Tendenz zu ? | X | | | | [Ocp](SOLID-Principle.md#o-open-closed-principle-ocp) | X | - | X | x | -
zumindest in Vorlage | X | | | | [Lsp](SOLID-Principle.md#l-liskov-s-substitution-principle-lsp) | ? | - | ?
(kann, muss nicht) | - | - | X | | | | [Isp](SOLID-Principle.md#i-interface-segregation-principle-isp) | ?/X | - | - | X
sollte, kann aber auch ? | -
zumindest in Vorlage | X | | | | [Dip](SOLID-Principle.md#d-dependency-inversion-principle-dip) | X | - | X | X | -
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_543.png](image_543.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_544.png](image_544.png) ## State Pattern ![image_409.png](image_409.png)