# 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 ## 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 -