GoF Design Patterns - welche verwenden Sie eigentlich? [geschlossen]

16

Ich versuche, meine Kollegen auf dem Gebiet der Entwurfsmuster auszubilden. Einige der ursprünglichen Gang of Four-Muster sind ein wenig esoterisch, daher frage ich mich, ob es eine Untergruppe von "wesentlichen" Mustern gibt, die alle Programmierer kennen sollten. Während ich die Liste durchschaue, denke ich, dass ich wahrscheinlich verwendet habe -

  • Abstrakte Fabrik
  • Fabrik Methode
  • Singleton
  • Brücke
  • Fassade
  • Befehl

Welche verwenden Sie in der Praxis und wofür verwenden Sie sie?

Link für diejenigen, die eine Liste von Mustern wünschen

Craig Schwarze
quelle
7
Meiner Meinung nach ist die Frage zu vage, um eine nützliche Diskussion zu liefern. Möchten Sie eine Antwort pro Muster oder eine Antwort pro Musterkombination?
Macke
Einige Gründe, warum Sie diese Muster verwenden, wären nützlich, da Sie sonst nur Konzepte auflisten ... Stellen Sie sich vor, Sie stellen die Frage: "Welche Schlüsselwörter verwenden Sie?" und Listen von " for, if, while...etc" zu sammeln - schwer zu messen, wie sinnlos das wäre.
ocodo
1
Ich bin nicht einverstanden mit Slomojo - ich denke, es wäre ziemlich praktisch zu wissen, welche Schlüsselwörter häufig verwendet wurden und welche nicht in einer Sprache waren. Gleiches gilt zum Beispiel für Basisklassen.
Craig Schwarze
1
Modifiziert es ein bisschen mehr - hoffentlich wird dies jetzt eine bessere Diskussion generieren.
Craig Schwarze
1
Welche Obstsorten essen Sie eigentlich? Ich bin gespannt, was Sie von dieser Frage erwarten. Wenn Sie ein Muster sehen, das von 3 oder 4 Personen verwendet wurde, das Sie jedoch nicht verwendet haben, müssen Sie es dann verwenden?
Marcie

Antworten:

4

Hier ist eine Liste derjenigen, die ich in der Praxis verwendet oder gesehen habe:

Singleton - Anwendungsobjekt in ASP.Net ist ein hervorragendes Beispiel dafür.

Adapter - Das Herstellen einer Verbindung zu Datenbanken kann normalerweise eine Adapter-Klasse beinhalten, zumindest in meinem Bereich der .Net-Inhalte.

Factory - General zum Generieren von Objekten, obwohl ich dies früher in einigen älteren klassischen ASPs gesehen habe.

Strategie - Ich hatte eine Anwendung, die für jeden Gerätetyp eine ähnliche Struktur für die Klasse hatte, die ich als Implementierung dieses Musters betrachten würde.

Fassade - In gewisser Hinsicht ähnelt dies dem Adapter-Muster, da es in der Regel mehrere Systeme miteinander verbindet.

JB King
quelle
1
Alle gültigen Verwendungen. Wenn Sie dies auch lesen, denken Sie daran, dass diese Muster sicherlich nicht auf diese beschränkt sind.
Boris
5

Die Autoren haben die Muster aus beobachteten Designs zusammengestellt, die sie in realen Anwendungen gefunden haben. Niemand wird wahrscheinlich alle von ihnen benutzen, aber sie werden alle benutzt.

Schmiede
quelle
Wofür haben Sie Smithco verwendet?
Craig Schwarze
@ Craigs Ich habe viele von ihnen verwendet. Die Autoren von Design Patterns haben eine Reihe guter Beispiele für jedes von ihnen beschriebene Muster. Der beste Vorschlag, den ich machen kann, ist, die Zeit damit zu verbringen, das Buch gründlich zu lesen.
Smithco
3

Dekorateur .

BEARBEITEN : In fast jedem Projekt, das über die 'triviale' Phase hinausgeht, wird eine IAction-Schnittstelle angezeigt (Details können abweichen):

// Programming Language does not matter
interface IAction {
     bool operateOn(Foo* target);
     string getDisplayName(); // useful for debugging and logging
};

Die nächste Stunde verbringe ich damit, viele kleine, fast triviale Klassen zu schreiben, die IAction implementieren. In Kombination sind sie sehr leistungsstark und flexibel.

ZB ein LogAction(schreiben, um die IAction zu protokollieren und auszuführen), NullAction(nichts tun und true zurückgeben), ActionList(eine Liste von IActions ausführen und die UND-Verknüpfung der Bools zurückgeben). In einigen Fällen ein AndAction(kurzgeschlossen oder nicht wieder das UND-ing von zwei Aktionen, könnte) OrAction, NotActionsinnvoll auch.

Obwohl technisch gesehen aus den obigen Beispielen nur die LogAction ein Decorator ist (die anderen arbeiten nicht mit genau 1 IAction), halte ich dies dennoch für eine Verallgemeinerung des Decorator-Musters, wenn ich eine ActionList von LogActions von IActions erstelle.

Sjoerd
quelle
Wofür verwendest du es?
Craig Schwarze
1
@CraigS Beispiel auf Anfrage hinzugefügt.
Sjoerd
Eigentlich sieht es eher nach einer Mischung aus Decorator und Composite aus, was in Ordnung ist, und es ist ein perfekter Beweis dafür, dass die Schwierigkeit bei Mustern nicht darin besteht, sie unabhängig voneinander zu verwenden, sondern sie zusammen zu mischen :)
Matthieu M.
Ja, das ist ein Klassiker. Es ist zusammengesetzt und wird mit dem Befehl verglichen. Es gibt tatsächlich einen Namen für dieses Muster: Es heißt "Specification" ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman
2

Ich gehe davon aus, dass Sie die Frage auf die Verwendung von Mustern in eigenem Code / Projekten beschränken möchten (keine Klassenbibliotheken und Frameworks von Drittanbietern).

Wie andere habe ich auch die Factory- Muster am häufigsten verwendet. Dann

  • Singleton : Heutzutage nicht so sehr, aber manchmal ist es notwendig, normalerweise für globale Konfigurationsdaten
  • Strategie und Template-Methode : Sehr häufig, zB zur Darstellung verschiedener Arten von Berechnungen in unserer App
  • Builder : zum Zusammenfassen der Ergebnisse von Transaktionen mit einem Mainframe-System zu Ausgabeobjekten (in einigen Fällen wird viel Text analysiert und große Objekthierarchien erstellt)
  • Befehl : Ich habe es vor vielen Jahren nur einmal implementiert, aber heutzutage verwende ich in unserem Java-Projekt gelegentlich Callables, die meiner Meinung nach im Grunde genommen Befehle sind
Péter Török
quelle
2

Ich habe viele der anderen verwendet, die bereits erwähnt wurden (Singleton, Factory, Builder, Command, Strategy, etc ...)

Eine, die ich noch nicht erwähnt habe, ist das Fliegengewicht, das ich häufig benutze. Ich habe unten ein Beispiel für eine Implementierung angegeben:

/**
 * Flyweight class representing OCR digits.
 * 
 * @author matt
 *
 */
public class Digit {
    /** Static flyweight map containing Digits which have been encountered. **/
    private static Map digits = new HashMap();

    /** The block of text representing Digit. **/
    private String blockRep = null;

    /** A map representing acceptable blocks of characters and the string representation of their
     * numerical equivalents.
     */
    public static final Map VALID_DIGITS;

    /** Enum of valid digits. **/
    public static enum DigitRep {
        ZERO    (   " _ \n" +
                    "| |\n" +
                    "|_|"       ),

        ONE (       "   \n" +
                    "  |\n" +
                    "  |"       ),

        TWO (       " _ \n" +
                    " _|\n" +
                    "|_ "       ),

        THREE   (   " _ \n" +
                    " _|\n" +
                    " _|"       ),

        FOUR    (   "   \n" +
                    "|_|\n" +
                    "  |"       ),

        FIVE    (   " _ \n" +
                    "|_ \n" +
                    " _|"       ),

        SIX     (   " _ \n" +
                    "|_ \n" +
                    "|_|"       ),

        SEVEN   (   " _ \n" +
                    "  |\n" +
                    "  |"       ),

        EIGHT   (   " _ \n" +
                    "|_|\n" +
                    "|_|"       ),

        NINE    (   " _ \n" +
                    "|_|\n" +
                    " _|"       );

        private String blockRep;

        DigitRep(String blockRep) {
            this.blockRep = blockRep;
        }

        @Override
        public String toString() {
            return blockRep;
        }
    }

    static {
        /* Initialize the map of acceptable character blocks. */
        Map tmpMap = new HashMap();
        tmpMap.put( DigitRep.ZERO.toString(),   "0");
        tmpMap.put( DigitRep.ONE.toString(),    "1");
        tmpMap.put( DigitRep.TWO.toString(),    "2");
        tmpMap.put( DigitRep.THREE.toString(),  "3");
        tmpMap.put( DigitRep.FOUR.toString(),   "4");
        tmpMap.put( DigitRep.FIVE.toString(),   "5");
        tmpMap.put( DigitRep.SIX.toString(),    "6");
        tmpMap.put( DigitRep.SEVEN.toString(),  "7");
        tmpMap.put( DigitRep.EIGHT.toString(),  "8");
        tmpMap.put( DigitRep.NINE.toString(),   "9");       
        VALID_DIGITS = Collections.unmodifiableMap(tmpMap);
    }

    /**
     * Private constructor to enforce flyweight/factory pattern.
     * 
     * @param blockRep
     */
    private Digit(String blockRep) {
        this.blockRep = blockRep;
    }

    /**
     * Flyweight factory method to create a Digit object from the "block"
     * representation of the digit.
     * @param blockRep The "block" representation of a digit.  Should look
     * something like:
     * " _ \n"
     * "|_|\n"
     * "|_|"
     * @return A flyweight Digit object representing the digit.
     */
    public static synchronized Digit getDigit(String blockRep) {
        Digit digit = digits.get(blockRep);
        if(digit == null) {
            digit = new Digit(blockRep);
            digits.put(blockRep, digit);
        }

        return digit;
    }

    /**
     * Determines whether or not the digit is valid.
     * @return true if the digit is valid, else false.
     */
    public boolean isValid() {
        return VALID_DIGITS.containsKey(blockRep);
    }

    /**
     * Accessor method to get the block representation of this digit.
     * 
     * @return
     */
    public String getBlockRep() {
        return blockRep;
    }

    @Override
    public String toString() {
        return VALID_DIGITS.containsKey(blockRep) ? VALID_DIGITS.get(blockRep) : "?";
    }
}
Matt Caldwell
quelle
1
+1 eines der weniger bekannten, aber immer noch unglaublich nützlichen Muster.
MattDavey
2

Die meisten der ursprünglichen Gang of Four-Muster werden heute noch verwendet, aber es gibt andere, die jetzt populär sind und nicht in dem Buch stehen.

Finden Sie eine Referenz für Design Patters in der Sprache, die Sie verwenden. Sie sind in der Regel konkreter und verwenden bestimmte Sprachmerkmale, um die Muster prägnanter und eleganter zu implementieren.

Drei großartige Ressourcen für Design Patterns:

Buch "Head First Design Patterns" - die Sprache der Wahl ist Java, ist aber für alle Sprachen relevant. dofactory Design Patterns - großartige und kostenlose Erklärungen zu .net-Designmustern mit Code. PluralSight - Design Patterns Library - diese ist kostenpflichtig, aber zu gut, um sie nicht in die Liste aufzunehmen.

Boris Yankov
quelle
1

Wenn Sie allgemeine Bibliotheken wie ACE verwenden, werden Sie am Ende mehr verwenden, als Sie zu verwenden glauben. Ich benutze Observer / Observable ausgiebig :-)

Aussenseiter
quelle
1

Ich habe mindestens einmal einen Builder verwendet (der gleiche Konvertierungsprozess kann HTML- oder Excel-Ausgaben erstellen).

Ich verwende häufig die Template-Methode (für JDBC-bezogene Aufgaben oder abstrakte Swing-Controller).

Einmal musste ich viele neue Funktionen in eine formularbasierte Anwendung umwandeln, was ein Durcheinander war. Ich konnte mich erst weiterentwickeln, nachdem ich das vorhandene Material zu einer State-Pattern-basierten Lösung umgestaltet hatte. (Nun, das meiste davon).

Ich benutze auch häufig Befehle (Swing Actions) und auch Beobachter.

Ich habe einmal eine Mememento-ähnliche Lösung zum Erkennen von Änderungen in Swing-Formen verwendet. Das Formular würde seinen Status serialisieren, was ich mit früheren Status verglichen habe (entspricht ()).

Karl
quelle
1

Ich glaube, ich habe die meisten in meiner Karriere. Das einzige, von dem ich sicher bin, dass ich es nicht verwendet habe, ist das Adaptermuster, das mit Mehrfachvererbung in dem Buch implementiert ist, da ich kein großer Fan von Mehrfachvererbung bin.

Raphael
quelle
1

Ich bin gern Dekorateur. Der einzige, den ich zu den genannten hinzufüge, ist Proxy.

Chuck Stephanski
quelle