Thứ Bảy, 27 tháng 5, 2017

Design Patterns - Wikipedia


Entwurfsmuster: Elemente wiederverwendbarer objektorientierter Software (1994) ist ein Softwareentwicklungsbuch, das Software-Entwurfsmuster beschreibt. Die Autoren des Buches sind Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides mit einem Vorwort von Grady Booch. Das Buch ist in zwei Teile gegliedert, wobei die ersten beiden Kapitel die Möglichkeiten und Fallstricke objektorientierter Programmierung untersuchen und die übrigen Kapitel 23 klassische Muster für das Software-Design beschreiben. Das Buch enthält Beispiele in C ++ und Smalltalk.

Es hat Einfluss auf das Gebiet der Softwareentwicklung genommen und gilt als wichtige Quelle für objektorientierte Designtheorie und -praxis. Über 500.000 Exemplare wurden auf Englisch und in 13 weiteren Sprachen verkauft. Die Autoren werden oft als Gang of Four ( GoF ) bezeichnet. [1]

History [

Das Buch begann am Eine "Birds of Feather" (BoF) Sitzung in der OOPSLA '90, "Towards a Architecture Handbook", von Bruce Anderson, wo Erich Gamma und Richard Helm sich trafen und ihr gemeinsames Interesse entdeckten. Später kamen Ralph Johnson und John Vlissides hinzu. [2] Das ursprüngliche Veröffentlichungsdatum des Buches war am 21. Oktober 1994 mit einem Copyright von 1995, daher wird es oft mit einem 1995-jährigen Titel zitiert, obwohl es 1994 veröffentlicht wurde. Das Buch wurde erstmals auf der OOPSLA-Sitzung im Oktober 1994 in Portland, Oregon, der Öffentlichkeit zugänglich gemacht. Im Jahr 2005 verlieh der ACM SIGPLAN den Autoren den diesjährigen Programmiersprachen Achievement Award in Anerkennung der Auswirkungen ihrer Arbeit "zur Programmierpraxis und zum Design von Programmiersprachen". [3] Seit März 2012 war das Buch in seiner 40. Auflage.

Einleitung, Kapitel 1 [ edit ]

Kapitel 1 ist eine Diskussion objektorientierter Designtechniken, basierend auf den Erfahrungen der Autoren, die ihrer Meinung nach zu einem guten Objekt führen würden. orientiertes Softwaredesign, einschließlich:

Die Autoren behaupten Folgendes als Vorteile von Schnittstellen gegenüber der Implementierung:

  • Clients wissen nicht, welche speziellen Objekttypen sie verwenden, solange das Objekt an der Schnittstelle haftet
  • Clients wissen nicht, welche Klassen diese Objekte implementieren. Clients wissen nur über die abstrakten Klassen, die das Interface definieren

Die Verwendung eines Interfaces führt auch zu dynamischen Bindungen und Polymorphismen, die zentrale Merkmale objektorientierter Programmierung sind.

Die Autoren bezeichnen die Vererbung als White-Box-Wiederverwendung mit White-Box in Bezug auf Sichtbarkeit, da die Interna von übergeordneten Klassen oft für Unterklassen sichtbar sind. Im Gegensatz dazu beziehen sich die Autoren auf die Objektkomposition (bei der Objekte mit klar definierten Schnittstellen zur Laufzeit dynamisch von Objekten verwendet werden, auf die Bezug genommen wird andere Objekte) als Black-Box-Wiederverwendung da im Code keine internen Details von zusammengesetzten Objekten sichtbar sein müssen.

Die Autoren diskutieren ausführlich die Spannung zwischen Vererbung und Verkapselung und geben an, dass Konstrukteure nach ihrer Erfahrung die Vererbung überfordern (Gang of Four 1995: 20). Die Gefahr wird wie folgt angegeben:

"Da bei der Vererbung eine Unterklasse Details der Implementierung ihres übergeordneten Objekts enthüllt, wird oft gesagt, dass" Vererbung die Kapselung bricht ". (Gang of Four 1995: 19)

Sie warnen, dass die Implementierung einer Unterklasse mit der Implementierung ihrer Elternklasse so verbunden sein kann, dass jede Änderung der Implementierung der Eltern die Subklasse zwingt, sich zu ändern. Darüber hinaus behaupten sie, dass eine Möglichkeit, dies zu vermeiden, darin besteht, nur von abstrakten Klassen zu erben. Sie weisen jedoch darauf hin, dass die Wiederverwendung von Code nur minimal ist.

Die Verwendung der Vererbung wird hauptsächlich empfohlen, wenn Sie die Funktionalität vorhandener Komponenten erweitern, den größten Teil des alten Codes wiederverwenden und relativ kleine Mengen neuen Codes hinzufügen.

Für die Autoren ist "Delegierung" eine extreme Form der Objektkomposition, die immer verwendet werden kann, um Vererbung zu ersetzen. Die Delegierung umfasst zwei Objekte: Ein Absender übergibt sich selbst an einen Delegierten, damit der Delegierte sich auf den Absender beziehen kann. Somit wird die Verbindung zwischen zwei Teilen eines Systems nur zur Laufzeit und nicht zur Kompilierzeit hergestellt. Der Callback-Artikel enthält weitere Informationen zur Delegierung.

Die Autoren diskutieren auch sogenannte parametrisierte Typen die auch als Generika (Ada, Eiffel, Java, C #, VB.NET und Delphi) oder Templates (C ++) bekannt sind. Damit können beliebige Typen definiert werden, ohne alle anderen verwendeten Typen anzugeben. Die nicht angegebenen Typen werden am Verwendungsort als Parameter angegeben.

Die Autoren geben zu, dass Delegierung und Parametrisierung sehr mächtig sind, fügen jedoch eine Warnung hinzu:

"Dynamische, stark parametrisierte Software ist schwieriger zu verstehen und zu erstellen als statische Software." (Gang of Four 1995: 21)

Die Autoren unterscheiden weiter zwischen 'Aggregation', wobei ein Objekt ein anderes Objekt "hat" oder "Teil eines anderen Objekts" ist (was impliziert, dass ein Aggregatobjekt und sein Besitzer eine identische Lebensdauer haben) und [19459004Bekanntschaftbei der ein Objekt lediglich ein anderes Objekt "kennt". Manchmal wird Bekanntschaft als "Assoziation" oder "Verwendungsbeziehung" bezeichnet. Bekannte Objekte fordern zwar gegenseitige Operationen an, sind jedoch nicht füreinander verantwortlich. Bekanntschaft ist eine schwächere Beziehung als Aggregation und deutet auf eine weitaus lockerere Kopplung zwischen Objekten hin, was für maximale Wartungsfreundlichkeit in einem Entwurf oft wünschenswert sein kann.

Die Autoren verwenden den Begriff "Toolkit", wo andere heute möglicherweise "Klassenbibliotheken" verwenden, wie in C # oder Java. In ihrem Sprachgebrauch sind Toolkits das objektorientierte Äquivalent von Unterprogrammbibliotheken, während ein 'Framework' eine Gruppe zusammenarbeitender Klassen ist, die einen wiederverwendbaren Entwurf für eine bestimmte Klasse von Software ausmachen. Sie stellen fest, dass Anwendungen schwer zu entwerfen sind, Toolkits schwieriger sind und Frameworks am schwersten zu entwerfen sind.

Fallstudie, Kapitel 2 [ edit ]

Kapitel 2 ist eine Schritt-für-Schritt-Fallstudie zum Entwurf eines "Was-Sie-Sehen-Was-Was-Was" -You-Get '(oder' WYSIWYG ') Dokumenteditor mit dem Namen Lexi. " (S. 33)

In diesem Kapitel werden sieben Probleme behandelt, die angesprochen werden müssen, um Lexi richtig zu gestalten, einschließlich aller Einschränkungen, die befolgt werden müssen. Jedes Problem wird eingehend analysiert und Lösungen vorgeschlagen. Jede Lösung wird vollständig erläutert, einschließlich Pseudo-Code und gegebenenfalls einer leicht modifizierten Version der Object Modeling Technique.

Schließlich wird jede Lösung direkt einem oder mehreren Entwurfsmustern zugeordnet. Es wird gezeigt, wie die Lösung eine direkte Implementierung dieses Entwurfsmusters ist.

Die sieben Probleme (einschließlich ihrer Einschränkungen) und ihre Lösungen (einschließlich der Muster, auf die verwiesen wird) lauten wie folgt:

Dokumentstruktur [ edit ]

Das Dokument ist "eine Anordnung grundlegender grafischer Elemente" wie Zeichen, Linien, andere Formen usw., die den gesamten Informationsgehalt erfassen des Dokuments "(S. 35). Die Struktur des Dokuments enthält eine Sammlung dieser Elemente. Jedes Element kann wiederum eine Unterstruktur anderer Elemente sein.

Probleme und Einschränkungen

  1. Text und Grafiken sollten auf dieselbe Weise behandelt werden (dh Grafiken sind keine abgeleiteten Textinstanzen oder umgekehrt)
  2. Die Implementierung sollte komplexe und einfache Strukturen behandeln in der gleichen Weise. Sie sollte den Unterschied zwischen beiden nicht kennen müssen.
  3. Spezifische Derivate abstrakter Elemente sollten spezielle analytische Elemente haben.

Solution and Pattern

Eine rekursive Komposition von 19459003 ist eine hierarchische Struktur von Elementen, die "immer komplexere Elemente aus einfacheren Elementen" (S. 36) aufbaut. Jeder Knoten in der Struktur kennt seine eigenen Kinder und deren Eltern. Wenn eine Operation für die gesamte Struktur ausgeführt werden soll, ruft jeder Knoten die Operation für die untergeordneten Elemente auf (rekursiv).

Dies ist eine Implementierung des zusammengesetzten Musters, bei dem es sich um eine Sammlung von Knoten handelt. Der Knoten ist eine abstrakte Basisklasse, und Ableitungen können entweder Blätter (Singular) oder Sammlungen anderer Knoten sein (die wiederum Blätter oder Sammlungsknoten enthalten können). Wenn eine Operation für das übergeordnete Element ausgeführt wird, wird diese Operation rekursiv in der Hierarchie weitergegeben.

Formatierung [ edit ]

Die Formatierung unterscheidet sich von der Struktur. Die Formatierung ist eine Methode zum Erstellen einer bestimmten Instanz der physischen Struktur des Dokuments. Dies umfasst das Aufteilen von Text in Zeilen, das Verwenden von Bindestrichen, das Anpassen der Randbreite usw.

Probleme und Einschränkungen

  1. Balance zwischen (Formatierungs-) Qualität, Geschwindigkeit und Speicherplatz
  2. Beibehaltung der Formatierung unabhängig von der Dokumentstruktur.

Lösung und Muster

Eine Compositor-Klasse kapselt den zum Formatieren einer Komposition verwendeten Algorithmus. Compositor ist eine Unterklasse des primitiven Objekts der Struktur des Dokuments. Ein Compositor verfügt über eine zugeordnete Instanz eines Composition-Objekts. Wenn ein Compositor seine Compose () ausführt, durchläuft er jedes Element seiner zugeordneten Komposition und ordnet die Struktur durch Einfügen von Row- und Column-Objekten nach Bedarf neu an.

Der Compositor selbst ist eine abstrakte Klasse, mit der abgeleitete Klassen unterschiedliche Formatierungsalgorithmen verwenden können (z. B. Doppelabstände, breitere Ränder usw.).

Das Strategiemuster wird verwendet, um dieses Ziel zu erreichen. Eine Strategie ist eine Methode zum Einkapseln mehrerer Algorithmen, die basierend auf einem sich ändernden Kontext verwendet werden sollen. In diesem Fall sollte die Formatierung unterschiedlich sein, je nachdem, ob Text, Grafiken, einfache Elemente usw. formatiert werden.

Verschönern der Benutzeroberfläche [ edit ]

Die Fähigkeit, die grafische Benutzeroberfläche zu ändern, mit der der Benutzer mit dem Dokument interagiert.

Probleme und Einschränkungen

  1. Markieren Sie eine Textseite mit einer Umrandung um den Bearbeitungsbereich.
  2. Bildlaufleisten, mit denen der Benutzer verschiedene Teile der Seite anzeigen kann.
  3. Benutzeroberflächenobjekte sollten nicht darüber informiert sein Verzierungen
  4. Vermeiden Sie eine "Klassenexplosion", die durch Unterklassen für "jede mögliche Kombination von Verzierungen" und Elementen (S. 44) hervorgerufen wird.

Solution and Pattern

Die Verwendung eines transparenten Gehäuses ermöglicht, dass Elemente, die das Verhalten der Komposition erhöhen, einer Komposition hinzugefügt werden. Diese Elemente, wie Border und Scroller, sind spezielle Unterklassen des einzelnen Elements. Dadurch kann die Komposition erweitert werden und effektiv zustandsähnliche Elemente hinzugefügt werden. Da diese Erweiterungen Teil der Struktur sind, werden ihre entsprechenden Operation () aufgerufen, wenn die Struktur Operation () aufgerufen wird. Dies bedeutet, dass der Client keine besonderen Kenntnisse oder Schnittstellen mit der Struktur benötigt, um die Verzierungen zu verwenden.

Dies ist ein Decorator-Muster, das einem Objekt Verantwortlichkeiten hinzufügt, ohne das Objekt selbst zu ändern.

Unterstützung mehrerer Look-and-Feel-Standards [ edit ]

Look-and-Feel bezieht sich auf plattformspezifische UI-Standards. Diese Standards "definieren Richtlinien, wie Anwendungen auf den Benutzer wirken und auf ihn reagieren" (S. 47).

Probleme und Einschränkungen

  1. Der Redakteur muss Standards für mehrere Plattformen implementieren, damit er tragbar ist.
  2. Einfache Anpassung an neue und aufkommende Standards.
  3. Ermöglicht die Änderung des Look-and-Feel zur Laufzeit (dh keine Hardcoding-Funktion)
  4. Für jede Elementkategorie (ScrollBar, Buttons usw.) müssen eine Reihe abstrakter Unterklassen eingerichtet sein.
  5. Für jede abstrakte Unterklasse gibt es eine Reihe konkreter Unterklassen, die unterschiedlich aussehen können -und fühlen sich Standard an. (ScrollBar mit MotifScrollBar und PresentationScrollBar für Motiv und Präsentationen)

Solution and Pattern

Da die Objekterstellung verschiedener konkreter Objekte zur Laufzeit nicht durchgeführt werden kann, muss der Objekterstellungsprozess abstrahiert werden. Dies geschieht mit einer abstrakten guiFactory, die die Erstellung von UI-Elementen übernimmt. Die abstrakte guiFactory hat konkrete Implementierungen wie MotifFactory, die konkrete Elemente des entsprechenden Typs (MotifScrollBar) erstellt. Auf diese Weise muss das Programm nur nach einer ScrollBar fragen und zur Laufzeit erhält es das richtige konkrete Element.

Dies ist eine abstrakte Fabrik. Eine reguläre Fabrik erstellt konkrete Objekte eines Typs. In einer abstrakten Fabrik werden abhängig von der konkreten Umsetzung der Fabrik selbst Objekte unterschiedlicher Art erstellt. Seine Fähigkeit, sich nicht nur auf konkrete Objekte zu konzentrieren, sondern auf ganze Familien von konkreten Objekten "unterscheidet sie von anderen Schöpfungsmustern, bei denen nur eine Art von Produktobjekt beteiligt ist" (S. 51).

Unterstützung von mehreren Fenstersystemen [ edit ]

So wie sich das Look-and-Feel-Verfahren bei den Plattformen unterscheidet, ist dies auch die Methode zur Behandlung von Fenstern. Jede Plattform zeigt, ordnet an, verarbeitet Eingaben und Ausgaben von und stellt Fenster unterschiedlich dar.

Probleme und Einschränkungen

  1. Der Dokumenteditor muss auf vielen der "wichtigen und weitgehend inkompatiblen Fenstersysteme" ausgeführt werden (S. 52).
  2. Eine Abstrakte Fabrik kann nicht verwendet werden. Aufgrund unterschiedlicher Standards gibt es nicht für jede Art von Widget eine gemeinsame abstrakte Klasse.
  3. Erstellen Sie kein neues, nicht dem Standard entsprechendes Fenstersystem

Solution and Pattern

Es ist möglich, "eigene abstrakte und konkrete Produktklassen" zu entwickeln, weil "alle Fenstersysteme im Allgemeinen dasselbe tun" (S. 52). Jedes Fenstersystem bietet Operationen zum Zeichnen von Grundformen, zum Symbolisieren / Deaktivieren, Ändern der Größe und zum Aktualisieren des Fensterinhalts.

Eine abstrakte Basisklasse Window kann von den verschiedenen Arten vorhandener Fenster abgeleitet werden, z. B. Anwendung, Symbol, Dialog. Diese Klassen enthalten Operationen, die mit Fenstern verknüpft sind, z. B. Umformen, grafische Aktualisierung usw. Jedes Fenster enthält Elemente, deren Draw () -Funktionen vom -Fenster aufgerufen werden eigene Draw-bezogene Funktionen.

Um zu vermeiden, dass für jede mögliche Plattform plattformspezifische Window-Unterklassen erstellt werden müssen, wird eine Schnittstelle verwendet. Die Klasse Window implementiert eine abstrakte Klasse Window ( WindowImp ). Diese Klasse wird dann wiederum in mehrere plattformspezifische Implementierungen mit jeweils plattformspezifischen Operationen abgeleitet. Daher wird für jeden Typ von Window nur ein Satz von Window -Klassen benötigt, und es wird nur ein Satz von WindowImp -Klassen für jede Plattform (und nicht für die Plattform) benötigt Kartesisches Produkt aller verfügbaren Typen und Plattformen). Außerdem erfordert das Hinzufügen eines neuen Fenstertyps keine Änderung der Plattformimplementierung oder umgekehrt.

Dies ist ein Brückenmuster. Window und WindowImp sind unterschiedlich, aber verwandt. Window beschäftigt sich mit Windowing im Programm, und WindowImp befasst sich mit Windowing auf einer Plattform. Einer von ihnen kann sich ändern, ohne den anderen ändern zu müssen. Mit dem Bridge-Muster können diese beiden "separaten Klassenhierarchien zusammenarbeiten, selbst wenn sie sich unabhängig voneinander entwickeln" (S. 54).

Benutzeroperationen [ edit ]

Alle Aktionen, die der Benutzer mit dem Dokument ausführen kann, einschließlich der Eingabe von Text, Ändern der Formatierung, Beenden, Speichern usw.

Probleme und Einschränkungen

  1. Auf Vorgänge muss über verschiedene Eingaben zugegriffen werden, z. B. eine Menüoption und eine Tastenkombination für denselben Befehl.
  2. Jede Option hat eine Schnittstelle, die veränderbar sein sollte
  3. Vorgänge werden in mehreren verschiedenen Klassen implementiert
  4. Um eine Kopplung zu vermeiden, dürfen zwischen den Klassen der Implementierung und der Benutzeroberfläche keine großen Abhängigkeiten bestehen.
  5. Die Befehle Rückgängig und Wiederherstellen müssen für die meisten Dokumentänderungsoperationen ohne willkürliche Begrenzung unterstützt werden auf die Anzahl der Rückgängig-Ebenen
  6. Funktionen sind nicht praktikabel, da sie nicht leicht rückgängig gemacht / wiederholt werden können, nicht einfach mit einem Zustand verknüpft werden können und schwer zu erweitern oder wiederzuverwenden sind.
  7. Menüs sollten wie hierarchisch behandelt werden Verbundstrukturen. Daher ist ein Menü ein Menüelement, das Menüelemente enthält, die andere Menüelemente usw. enthalten können.

Solution and Pattern

Jeder Menüpunkt wird nicht mit einer Parameterliste instanziiert, sondern mit einem Command -Objekt.

Befehl ist ein abstraktes Objekt, das nur eine einzige abstrakte Methode hat Execute () . Abgeleitete Objekte erweitern das Execute () -Verfahren entsprechend (d. H. Der PasteCommand.Execute () würde den Zwischenablagepuffer des Inhalts verwenden). Diese Objekte können von Widgets oder Schaltflächen genauso einfach verwendet werden wie von Menüelementen.

Zur Unterstützung von Undo und Redo Command wird auch Unexecute () und Reversible () gegeben. In abgeleiteten Klassen enthält ersterer Code, der diesen Befehl rückgängig macht, und letzteren gibt einen booleschen Wert zurück, der definiert, ob der Befehl rückgängig gemacht werden kann. Mit Reversible () können einige Befehle nicht rückgängig gemacht werden, z. B. ein Befehl zum Speichern.

Alle ausgeführten -Befehle werden in einer Liste mit einer Methode geführt, mit der ein "anwesender" Marker direkt nach dem zuletzt ausgeführten Befehl gehalten wird. Eine Aufforderung zum Rückgängigmachen ruft den Befehl Command.Unexecute () direkt vor "present" auf und bewegt dann "present" einen Befehl zurück. Umgekehrt wird eine Redo -Anforderung Command.Execute () nach "present" aufrufen und "present" nach vorne verschieben.

Bei diesem Kommando handelt es sich um eine Implementierung des Kommandomusters. Es kapselt Anforderungen in Objekte und verwendet eine gemeinsame Schnittstelle, um auf diese Anforderungen zuzugreifen. Auf diese Weise kann der Client verschiedene Anforderungen verarbeiten, und Befehle können in der gesamten Anwendung verstreut sein.

Rechtschreibprüfung und Silbentrennung [ edit ]

Dies ist die Fähigkeit des Dokumenteditors, den Inhalt eines Dokuments textuell zu analysieren. Obwohl es viele Analysen gibt, die ausgeführt werden können, stehen die Rechtschreibprüfung und die Formatierung der Silbentrennung im Vordergrund.

Probleme und Einschränkungen

  1. Mehrere Möglichkeiten zur Überprüfung der Rechtschreibung und zum Erkennen von Bindestrichungspunkten ermöglichen
  2. Erweiterungen für spätere Analysen zulassen (z. B. Wortanzahl, Grammatikprüfung)
  3. Durchlaufen Inhalt eines Textes ohne Zugriff auf die tatsächliche Struktur des Textes (z. B. Array, verknüpfte Liste, Zeichenfolge)
  4. Erlaubt das Durchqueren eines Dokuments (Anfang bis Ende, Ende bis Anfang, alphabetische Reihenfolge usw.)

und Muster

Durch das Entfernen des Integer-basierten Index aus dem Basiselement kann eine andere Iterationsschnittstelle implementiert werden. Dies erfordert zusätzliche Methoden für das Durchlaufen und das Abrufen von Objekten. Diese Methoden werden in eine abstrakte Schnittstelle Iterator gestellt. Jedes Element implementiert dann eine Ableitung des -Iterators abhängig davon, wie dieses Element seine Liste führt ( ArrayIterator LinkListIterator usw.).

Funktionen für das Durchsuchen und Abrufen werden in die abstrakte Iterator-Schnittstelle gestellt. Zukünftige Iteratoren können basierend auf dem Typ der Liste, durch die sie durchlaufen werden, abgeleitet werden, z. B. Arrays oder verknüpfte Listen. Unabhängig von der Art der Indizierungsmethode, die eine Implementierung des Elements verwendet, wird es den geeigneten Iterator haben.

Dies ist eine Implementierung des Iterator-Musters. Auf diese Weise kann der Client eine beliebige Objektauflistung durchlaufen, ohne direkt auf den Inhalt der Auflistung zugreifen zu müssen oder sich über den Typ der von der Struktur der Auflistung verwendeten Auflistung zu sorgen.

Nachdem nun Traversal verarbeitet wurde, können die Elemente einer Struktur analysiert werden. Es ist nicht möglich, jede Art von Analyse in die Elementstruktur selbst einzubauen. Jedes Element müsste codiert werden, und ein Großteil des Codes wäre für ähnliche Elemente gleich.

Stattdessen wird eine generische CheckMe () -Methode in die abstrakte Klasse des Elements eingebaut. Jeder Iterator erhält einen Verweis auf einen bestimmten Algorithmus (wie Rechtschreibprüfung, Grammatikprüfung usw.). Wenn dieser Iterator seine Sammlung durchläuft, ruft er [CheckMe] jedes Elements auf und übergibt den angegebenen Algorithmus. CheckMe gibt dann einen Verweis auf sein Element an den Algorithmus zur Analyse zurück.

Um eine Rechtschreibprüfung durchzuführen, erhält ein Front-to-End-Iterator einen Verweis auf ein Objekt SpellCheck . Der Iterator würde dann auf jedes Element zugreifen und seine Methode CheckMe () mit dem Parameter SpellCheck ausführen. Jedes CheckMe würde dann den SpellCheck aufrufen und einen Verweis auf das entsprechende Element übergeben.

Auf diese Weise kann jeder Algorithmus mit jeder Durchlaufmethode verwendet werden, ohne dass ein Code hart miteinander gekoppelt wird. Zum Beispiel kann "Suchen" als "Nächstes suchen" oder "Vorheriges suchen" verwendet werden, abhängig davon, ob ein "Vorwärts" -Iterator oder ein "Rückwärts" -Iterator verwendet wurde.

Außerdem können die Algorithmen selbst für den Umgang mit verschiedenen Elementen verantwortlich sein. Beispielsweise würde ein SpellCheck -Algorithmus ein Graphic -Element ignorieren, anstatt jedes Graphic -derivierte Element so programmieren zu müssen, dass es sich nicht an einen SpellCheck sendet .

Muster nach Typ [ edit ]

Creational [ edit ]

Creation-Muster sind diejenigen, die Objekte für Sie erzeugen, anstatt sie zu haben Sie instanziieren Objekte direkt. Dies gibt Ihrem Programm mehr Flexibilität bei der Entscheidung, welche Objekte für einen bestimmten Fall erstellt werden müssen.

Strukturell [ edit ]

Diese betreffen die Klassen- und Objektzusammensetzung. Sie verwenden Vererbung, um Schnittstellen zu erstellen, und definieren Methoden, um Objekte zu erstellen, um neue Funktionen zu erhalten.

  • Mit dem Adapter können Klassen mit inkompatiblen Schnittstellen zusammenarbeiten, indem sie ihre eigene Schnittstelle um die einer bereits vorhandenen Klasse wickeln.
  • Bridge entkoppelt eine Abstraktion von ihrer Implementierung, sodass die beiden unabhängig voneinander variieren können.
  • Composite besteht aus null- oder mehrere ähnliche Objekte, so dass sie als ein Objekt bearbeitet werden können.
  • Decorator fügt Verhalten in einer vorhandenen Methode eines Objekts dynamisch hinzu oder setzt diese außer Kraft.
  • Facade bietet eine vereinfachte Schnittstelle zu einem großen Codekörper.
  • Flyweight reduziert die Kosten für die Erstellung und Bearbeitung einer großen Anzahl ähnlicher Objekte.
  • Proxy stellt einen Platzhalter für ein anderes Objekt bereit, um den Zugriff zu steuern, Kosten zu reduzieren und die Komplexität zu reduzieren.

Behavioral [] ]]

Die meisten dieser Entwurfsmuster befassen sich speziell mit der Kommunikation zwischen Objekten .

  • Verantwortungskette delegiert Befehle an eine Kette von Verarbeitungsobjekten.
  • Mit dem Befehl werden Objekte erstellt, die Aktionen und Parameter einschließen.
  • Der Interpreter implementiert eine spezialisierte Sprache.
  • Iterator greift sequenziell auf die Elemente eines Objekts zu, ohne dessen Elemente freizulegen zugrunde liegende Darstellung.
  • Mediator ermöglicht die lose Kopplung zwischen Klassen, indem es die einzige Klasse ist, die über detaillierte Kenntnisse ihrer Methoden verfügt.
  • Memento bietet die Möglichkeit, ein Objekt in den vorherigen Zustand (undo) zurückzusetzen.
  • Observer ist ein Publish / Subscribe-Muster, das es einer Reihe von Beobachterobjekten ermöglicht, ein Ereignis zu sehen.
  • State erlaubt einem Objekt, sein Verhalten zu ändern, wenn sich sein interner Zustand ändert.
  • Mit der Strategie kann einer aus einer Familie von Algorithmen ausgewählt werden -fly zur Laufzeit.
  • Die Schablonenmethode definiert das Skelett eines Algorithmus als abstrakte Klasse, damit seine Unterklassen konkretes Verhalten liefern können.
  • Besucher trennt sich ein Algorithmus aus einer Objektstruktur durch Verschieben der Hierarchie von Methoden in ein Objekt.

Kritik [ edit ]

Kritik wurde auf das Konzept von Softwaredesign-Mustern allgemein gerichtet Design Patterns speziell. Ein Hauptkritikpunkt von Design Patterns besteht darin, dass seine Muster lediglich eine Problemumgehung für fehlende Features in C ++ sind. Sie ersetzen elegante abstrakte Merkmale durch langwierige konkrete Muster und werden im Wesentlichen zu einem "menschlichen Compiler" oder "generieren die Erweiterungen einiger" von Hand macro ". [4] Peter Norvig demonstriert, dass 16 von 23 Mustern in Design Patterns in Lisp oder Dylan vereinfacht oder eliminiert werden (direkte Sprachunterstützung). [5] . Ähnliche Beobachtungen wurden von Hannemann und gemacht Kiczales, der mehrere der 23 Entwurfsmuster unter Verwendung einer Aspekt-orientierten Programmiersprache (AspectJ) implementierte und zeigte, dass Abhängigkeiten auf Codeebene aus den Implementierungen von 17 der 23 Entwurfsmuster entfernt wurden und dass die Aspekt-orientierte Programmierung die Implementierung des Designs vereinfachen könnte [6]

Paul Graham schrieb: [4]

Wenn ich in meinen Programmen Muster sehe, betrachte ich dies als Zeichen von Schwierigkeiten. Die Form eines Programms sollte nur das Problem widerspiegeln, das gelöst werden muss. Jede andere Regelmäßigkeit im Code ist für mich zumindest ein Zeichen, dass ich Abstraktionen benutze, die nicht stark genug sind - oft, dass ich die Erweiterungen eines Makros, das ich schreiben muss, von Hand generiere.

Es gab auch humorvolle Kritik, wie zum Beispiel einen Schauprozess bei OOPSLA '99 am 3. November 1999 [7][8][a] und eine Parodie des Formats von Jim Coplien mit dem Titel "Kansas City Air Conditioner".

Siehe auch [ edit ]

Referenzen [ edit

Không có nhận xét nào:

Đăng nhận xét