Site Tools


Sidebar

My Sidebar

  • Network
  • Operating Systems
    • Linux
    • Windows
    • FRTOS
Hotfix release available: 2024-02-06b "Kaos". upgrade now! [55.2] (what's this?)
Hotfix release available: 2024-02-06a "Kaos". upgrade now! [55.1] (what's this?)
New release available: 2024-02-06 "Kaos". upgrade now! [55] (what's this?)
Hotfix release available: 2023-04-04b "Jack Jackrum". upgrade now! [54.2] (what's this?)
Hotfix release available: 2023-04-04a "Jack Jackrum". upgrade now! [54.1] (what's this?)
New release available: 2023-04-04 "Jack Jackrum". upgrade now! [54] (what's this?)
Hotfix release available: 2022-07-31b "Igor". upgrade now! [53.1] (what's this?)
Hotfix release available: 2022-07-31a "Igor". upgrade now! [53] (what's this?)
New release available: 2022-07-31 "Igor". upgrade now! [52.2] (what's this?)
New release candidate 2 available: rc2022-06-26 "Igor". upgrade now! [52.1] (what's this?)
New release candidate available: 2022-06-26 "Igor". upgrade now! [52] (what's this?)
Hotfix release available: 2020-07-29a "Hogfather". upgrade now! [51.4] (what's this?)
design_patterns

Design Patterns

Ein Muster ist eine Lösung eines Problems in einem bestimmten Kontext.

  • Der Kontext ist die Situation, in der das Muster angewendet wird. Es sollte eine wiederkehrende Situation sein
  • Das Problem umfasst das Ziel, das Sie in diesem Kontext erreichen möchten, aber auch alle Einschränkungen (oder Randbedingungen), die in dem Kontext auftreten können.
  • Die Lösung ist das, was Sie gern hätten: Ein allgemeiner Entwurf, mit dem jeder das Ziel erreichen und diesen Satz von Einschränkungen überwinden kann.

Merkspruch: Wenn Sie in einem bestimmten Kontext einem Problem gegenüberstehen und das Erreichen des Ziels nur mit gewissen Einschränkungen möglich ist, können Sie ein Muster anwenden, das zu einer Lösung für dieses Ziel und die zugehörigen Einschränkungen führt.

Musterkategorien:

Erzeugungsmuster beinhalten die Instantiierung von Objekten: sie alle bieten einen Weg, einen Client von den Objekten zu entkoppeln, die er instantiieren muss.

  • Singleton
  • Builder
  • Prototype
  • Factory Method
  • Abstract Factory

Verhaltensmuster haben all damit zu tun, wie Klassen und Objekte miteinander in Wechselwirkung stehen und die Zuständigkeiten untereinander aufteilen.

  • Mediator
  • Visitor
  • Template Method
  • Iterator
  • Command
  • Memento
  • Interpreter
  • Observer
  • Chain of Responsibility
  • State
  • Strategy

Strukturmuster ermöglichen die Zusammensetzung von Klassen oder Objekten zu größeren Strukturen.

  • Proxy
  • Decorator
  • Composite
  • Facade
  • Flyweigth
  • Bridge
  • Adapter

Decorator
Packt ein Objekt ein und fügt dabei neues Verhalten hinzu

State
Kapselt zustandsbasiertes Verhalten und wechselt durch Delegieren zwischen den Verhaltensweisen.

Iterator
Bietet eine Möglichkeit, eine Sammlung von Objekten zu durchqueren, ohne die Implementierung der Sammlung zu offenbaren.

Facade
Vereinfacht die Schnittstelle für eine Gruppe von Klassen.

Strategy
Kapselt austauschbares Verhalten und entscheidet mittels Delegierung, welches Verhalten verwendet wird.

Proxy
Umschließt ein Objekt und kontrolliert so den Zugriff darauf

Factory Method
Unterklassen entscheiden, welche konkreten Klassen erzeugt werden.

Adapter
Umschließt ein Objekt und stellt eine andere Schnittstelle dafür zur Verfügung.

Observer
Ermöglicht die Benachrichtigung von Objekten, wenn sich eine Zustand ändert.

Template Method
Unterklassen entscheide, wie die Schritte ein einem Algorithmus implementiert werden.

Composite
Clients behandeln Sammlungen von Objekten und Einzelobjekten auf gleiche Weise.

Singleton
Sorgt dafür, dass nur genau ein Objekt erzeugt wird.

Abstract Factory
Ermöglicht des einem Client, Familien von Objekten zu erstellen, ohne konkrete Klassen anzugeben.

Command
Kapselt einen Auftrag als in Objekt.

Punkt für Punkt:

  • Verwenden Sie Muster in Ihren Entwürfen nur dann, wenn es sich auf natürliche Weise ergibt, und nicht zwangsweise, nur um ein Muster zu benutzen.
  • Entwurfsmuster sind nicht in Stein gemeißelt; Sie können sie so anpassen und zurecht biegen, wie Sie sie gerade brauchen.
  • Verwenden Sie immer die einfachste Lösung, die Ihren Anforderungen entspricht, selbst wen sie kein Muster umfasst.
  • Studieren Sie Musterkataloge, um sich mit Mustern und den Beziehungen zwischen Ihnen vertraut zu machen.
  • Mit Musterklassifikationen (oder -kategorien) lassen sich Muster in Gruppen einteilen. Wenn es Ihnen weiterhilft, benutzen Sie sie.
  • Um selbst Muster zu schreiben, müssen Sie viel Engagement, Zeit und Geduld mitbringen, und Sie müssen bereit sein, eine Menge Code-Verbesserungen durchzuführen.
  • Denken Sie daran, dass die meisten Muster, denen Sie begegnen werden, Anpassungen existierender Muster sind und keine neuen Muster.
  • Erweitern Sie das gemeinsame Vokabular in Ihrem Team - einer der größten Vorteile, die Sie aus der Verwendung von Mustern ziehen können.
  • Wie jede Gemeinschaft hat auch die Mustergemeinde ihren eigenen Fachjargon. Lassen Sie sich davon nicht abschrecken.

OO-Basics

  • Abstraction
  • Encapsulation
  • Polymorphism
  • Inheritance

OO-Patterns

Strategy

Definiert eine Familie von Algorithmen, kapselt sie einzeln und macht sie austauschbar. Das Stratgegy-Muster ermöglicht es, den Algorithmus unabhängig von den Clients variieren zu lassen, die ihn einsetzen.

Punkt für Punkt:

  • Sie werden nicht allein dadurch zu einem guten OO-Designer, dass Sie die OO-Basics beherrschen.
  • Gute OO-Entwürfe sind wieder verwendbar, erweiterbar und wartbar.
  • Muster zeigen Ihnen, wie Sie Systeme mit guten OO-Entwurfseigenschaften entwerfen.
  • Muster sind bewährte objektorientierte Erfahrung.
  • Muster verschaffen Ihnen keinen Code, sie bieten Ihnen allgemeine Lösungen zu Entwurfsproblemen. Sie wenden diese auf spezifische Anwendung an.
  • Muster werden nicht erfunden, sie werden entdeckt.
  • Die meisten Muster und Prinzipien befassen sich mit Fragen der Änderungen an Software.
  • Die meisten Muster ermöglichen es, dass ein Teil des Systems unabhängig von allen anderen Teilen variieren kann.
  • Wir versuchen, in einem System das zu identifizieren, was sich ändert, um es zu kapseln.
  • Muster bieten eine gemeinsame Sprache, die Ihre Kommunikation mit anderen Entwicklern optimieren kann.

Observer

Definiert eine Eins-zu-viele-Abhängigkeit zwischen Objekten der Art, dass alle abhängigen Objekte automatisch benachrichtigt und aktualisier werden, wenn sich der Zustand des einen Objekts ändert.

Punkt für Punkt:

  • Das Observer-Muster definiert ein Eins-zu-viele-Verhältnmis zwischen Objekten.
  • Subjekte oder, wie wir sie auch kennen, Observables aktualisieren Beobachter über eine gemeinsame Schnittstelle.
  • Die Beobachter sind insofern locker angebunden, als das Obervable über sie nichts anderes weiß, als dass sie das Interface Observer implementieren.
  • Sie können Daten aus dem Observable herausgeben oder herausziehen, wenn Sie das Muster verwenden (wobei das Herausziehen als die “richtigere” Methode betrachtet wird).
  • Verlassen Sie sich nicht auf eine bestimmte Reihenfolge der Benachrichtigung Ihrer Beobachter.

Decorator

Fügt einem Objekt dynamisch zusätzliche Verantwortlichkeiten hinzu. Dekorierer bieten eine flexible Alternative zur Ableitung von Unterklassen zum Zweck der Erweiterung der Funktionalität.

Punkt für Punkt:

  • Vererbung ist eine Form von Erweiterung, aber nicht notwendigerweise der beste Weg, um Ihren Entwürfen Flexibilität zu verleihen.
  • Unsere Entwürfe sollten die Erweiterung von Verhalten ermöglichen, ohne dass dazu bestehender Code geändert werden müsste.
  • Oft können Komposition und Delegierung verwendet werden, um zur Laufzeit neue Verhalten hinzuzufügen.
  • Für die Erweiterung von Verhalten bietet das Decorator-Muster eine Alternative zur Ableitung von Unterklassen.
  • Das Decorator-Muster schließt einen Satz von Dekorierer-Klassen ein, die verwendet werden, um konkrete Komponenten einzupacken.
  • Dekorierer-Klassen spiegeln den Typ der Komponente wider, die sie dekorieren. (Sie haben tatsächlich den gleichen Typ wie die Komponente, die sie dekorieren, entweder durch Vererbung oder durch die Implementierung eines Interface.)
  • Dekorierer ändern das Verhalten der Komponente, indem sie vor und/oder nach (oder auch an Stelle von) Methodenaufrufen auf der Komponente neue Funktionalitäten hinzufügen.
  • Sie können eine Komponente mit einer beliebigen Zahl von Dekorierern einpacken.
  • Dekorierer sind für die Clients der Komponente überlichweise transparent, außer wenn sich der Client auf den konkreten Type der Komponente stützt.
  • Dekorierer können in Ihren Entwürfen zu vielen kleinen Objekten führen, und eine übermäßige Verwendung kann den Code unübersichtlich machen.

Factory

Factory Method

Definiert eine Schnittstelle zur Erstellung eines Objekts, lässt aber die Unterklassen entscheiden, welche Klassen instantiiert werden. Factory Method ermöglicht einer Klasse, die Instantiierung in Unterklassen zu verlagern.

Abstract Factory

Bietet eine Schnittstelle zum Erstellen von Familien verwandter oder zusammenhängender Objekte an, ohne konkrete Klassen anzugeben.

Punkt für Punkt:

  • Alle Factories kapseln die Objekt-Erstellung.
  • Die einfache Fabrik ist eine umkomlizierte Möglichkeit, Clients von konkreten Klassen zu entkoppeln, ist aber kein echtes Entwurfsmuster.
  • Factory Method stützt sich auf Vererbung: Die Objekterstellung wird an Unterklassen delegiert, die die Fabrikmethode implementieren, um Objekte zu erstellen.
  • Abstract Factory stützt sich auf Objekt-Komposition: Die Objekt-Erstellung ist in Methoden implementiert, die in der Fabrik-Schnittstelle vorgegeben ist.
  • Alle Factory-Muster fördern lockere Bindung, indem sie für Ihre Anwendung die Abhängigkeit von konkreten Klassen reduzieren.
  • Der Zweck von Factory-Method ist es, einer Klasse zu ermöglichen, die Instantiierung bis in ihre Unterklassen zu verzögern.
  • Der Zweck der Abstract Factory ist es, Familien verwandter Objekte zu erstellen, ohne dabei von den konkreten Klassen abhängig zu sein.
  • Das Prinzip der Umkehrung der Abhängigkeiten leitet uns an, Abhängigkeiten von konkreten Typen zu vermeiden und Abstraktion anzustreben.
  • Factories sind eine mächtige Technik, um auf Abstraktion statt auf konkrete Klassen zu implementieren.

Command

Kapselt einen Auftrag als ein Objekt und ermöglicht so, andere Objekte mit verschiedenen Aufträgen zu parametrisieren, Aufträge in Warteschlangen einzureihen oder zu protokollieren oder das Rückgängigmachen von Operationen zu unterstützen.

Punkt für Punkt:

  • Das Command-Muster entkoppelt ein Objekt und versendet eine Auftrag an ein anderes, das weiß, wie es ihn ausführen muss.
  • Ein Befehl-Objekt steht im Zentrum dieses Entkoppelns und kapselt einem Empfänger mit einer Aktion (oder einer Gruppe von Aktionen).
  • Ein Aufrufer beauftragt ein Befehl-Objekt, indem er dessen ausführen()-Methode aufruft, die diese Aktion auf dem Empfänger aufruft.
  • Aufrufer können mit Befehlen sogar dynamisch zur Laufzeit parmetrisiert werden.
  • Befehle können das Rückgängimachen von Befehlen unterstützen, indem sie eine rückgängig()-Methode implementieren, die das Objekt in den Zustand zurückversetzt, der bestand, als die Methode ausführen() das letzte Mal aufgerufen wurde.
  • Makro-Befehle sind eine einfache Erweiterung des Command-Muster, die es ermöglichen, mehrere Befehle aufzurufen. Auch Makro-Befehle können problemlos eine Rückgänig-Operation unterstützen.
  • In der Praxis ist es nicht selten, das “kluge” Befehl-Objekte den Auftrag selbst implementieren, anstatt ihn an einen Empfänger zu delegieren.
  • Befehle können auch verwendet werden, um Loggings und Transaktionsysteme zu implementieren.

Adapter, Facade

Adapter

Das Adapter-Muster konvertiert die Schnittstelle einer Klasse in die Schnittstelle, die der Client erwartet. Adapter ermöglichen die Zusammenarbeit von Klassen, die ohne nicht zusammenarbeiten könnten, weil sie inkompatible Schnittstellen haben.

Facade

Das Facade-Muster bietet eine vereinheitliche Schnittstelle für einen Satz von Schnittstellen eines Basissystems. Die Fassade definiert eine hochstufigere Schnittstelle, die die Verwendung des Basissystems vereinfacht.

Punkt für Punkt:

  • Nehmen Sie Adapter, wenn Sie eine bestehende Klasse verwenden müssen und ihre Schnittstelle nicht der entspricht, die Sie benötigen.
  • Verwenden Sie Facade, wenn Sie eine größere Schnittstelle oder eine komplexe Menge von Schnittstellen vereinfachen müssen.
  • Ein Adapter ändert eine Schnittstelle in die, die ein Client erwartet.
  • Eine Fassade entkoppelt eine Client von einem komplexen Basissystem.
  • Je nach Größe und Komplexität einer Ziel-Schnittstelle kann es etwas Arbeit sein, einen Adapter zu implementieren.
  • Bei der Implementierung einer Fassade ist es erforderlich, dass man die Fassade mit ihrem Basissystems zusammensetzt und Delegierung verwendet, um die Arbeit der Fassade durchzuführen.
  • Es gibt zwei Formen des Adapter-Musters: Objekt- und Klassen-Adapter. Für Klassen-Adapter ist Mehrfachvererbung erforderlich.
  • Für ein Basissystem können Sie mehr als eine Fassade implementieren.
  • Ein Adapter umhüllt ein Objekt, um seine Schnittstelle zu ändern, ein Dekorierer umhüllt ein Objekt, um neue Verhalten und Verantwortlichkeiten hinzuzufügen, eine Fassade umhüllt einen Satz von Objekten, um die Schnittstelle zu vereinfachen.

Template Method

Definiert in einer Methode das Gerüst eines Algorithmus und überlässt einige Schritte den Unterklassen. Template Method erlaubt Unterklassen, bestimmte Schritte des Algorithmus neu zu definieren, ohne die Struktur des Algorithmus zu ändern.

Punkt für Punkt:

  • Eine “Template-Methode” definiert die Schritte eines Algorithmus und überlässt die Implementierung dieser Schritte den Unterklassen.
  • Das Template Method-Muster liefert uns eine wichtige Technik für die Code-Wiederverwendung.
  • Die abstrakte Klasse der Template-Methode kann konkrete Methoden, abstrakte Methoden und Hooks definieren.
  • Abstrakte Methoden werden von den Unterklassen implementiert.
  • Hooks sind Methoden, die in der abstrakten Klasse nichts tun oder nur ein Default-Verhalten anbieten, aber in den Unterklassen überschrieben werden können.
  • Um zu verhindern, dass Unterklassen den Algorithmus in der Template-Methode ändern, wied die Template-Methode als final deklariert.
  • Das Hollywood-Prinzip leitet uns an, Entscheidungsprozesse in Highlevel-Module zu packen. Diese entscheiden, wie und wann die Lowlevel-Module aufgerufen werden.
  • Sie werden Code aus dem wirklichen Leben auf viele Verwendungen des Template Method-Musters stoßen, dürfen aber (wie bei jedem Muster) nicht erwarten, dass diese so entworfen sind, wie die Theorie sie beschreibt.
  • Die Muster Strategy und Template Method kapseln beide Algorithmen, das ein über Vererbung und das andere über Komposition.
  • Factory Method ist eine Spezialisierung von Template Method.

Iterator

Bietet eine Möglichkeit, auf die Elemente in einem Aggregat-Objekt sequenziell zuzugreifen, ohne die zu Grunde liegende Implementierung zu offenbaren.

Punkt für Punkt:

  • Ein Iterator ermöglicht Zugriff auf die Elemente eines Aggregats, ohne seine interne Struktur zu offenbaren.
  • Ein Iterator übernimmt die Aufgabe, über ein Aggregat zu iterieren, und kapselt es in einem anderen Objekt.
  • Wenn wir einen Iterator verwenden, erlösen wir das Aggregat von der Verantwortung, Operationen für die Durchquerung seiner Daten zu Verfügung zu stellen.
  • Ein Iterator bietet eine allgemeine Schnittstelle für die Durchquerung der Elemente eines Aggregats und ermöglicht es Ihnen, beim Schreiben von Code, der die Elemente eines Aggregats verwendet, Polymorphismus zu verwenden.
  • Wir sollen danach streben, dass jede Klasse nur eine Verantwortlichkeit zugewiesen wird.

Composite

Ermöglicht Ihnen, Objekten zu einer Baumstruktur zusammenzusetzen, um Teil/Ganzes-Hierarchien auszudrücken. Das Composite-Muster erlaubt den Clients, individuelle Objekte und Zusammensetzungen von Objekten auf gleiche Weise zu behandeln.

Punkt für Punkt:

  • Das Composite-Muster bietet eine Struktur, die einzelne Objekte und Komposita aufnehmen kann.
  • Das Composite-Muster erlaubt Clients, Komposita und einzelne Objekte auf gleiche Weise zu behandeln.
  • Jedes Objekt in einer zusammengesetzten Struktur ist eine Komponente. Komponenten können andere Komponenten oder Blattknoten sein.
  • Bei der Implementierung von Composite gibt es viele Designkompromisse. Sie müssen eine Ausgleich zwischen Transparent und Sicherheit und Ihren Anforderungen finden.

Zusammengesetzte Muster

Ein zusammengesetztes Muster kombiniert zwei oder mehrere Muster zur einer Lösung für ein wiederkehrendes oder allgemeines Problem.

Punkt für Punkt:

  • Das Model-View-Controller-Mustger (MVC) ist ein zusammengesetztes Muster, bestehend aus Observer-, Strategy- und Composite-Muster.
  • Das Model nutzt das Observer-Muster; so kann es Beobachter auf dem aktuellen Stand halten und dennoch von ihnen entkoppelt bleiben.
  • Der Controller ist das Strategy-Objekt für den View. Der View kann verschiedene Implementierungen des Controllers benutzen, um unterschiedliches Verhalten zu zeigen.
  • Der View nutzt das Composite-Muster für die Implementierung der Benutzerschnittstelle. Diese besteht in der Regel aus verschachtelten Komponenten wie Panels, Frames und Buttons.
  • Diese Muster arbeiten zusammen, um die drei Akteure im MVC-Model zu entkoppeln. So bleibt das Design klar und flexibel.
  • Mit dem Adapter-Muster lässt sich ein neues Model an ein vorhandenes View/Controller-Paar anpassen.
  • Model 2 ist ein Anpassung des MVC für Webanwendungen.
  • Im Model 2 ist der Controller als Servlet implementiert und der View als JSP & HTML.
design_patterns.txt · Last modified: 2024/09/16 14:29 by 172.19.0.1