Modèles de conception GoF - lesquels utilisez-vous réellement? [fermé]

16

J'essaie d'éduquer mes collègues dans le domaine des modèles de conception. Certains des motifs originaux de Gang of Four sont un peu ésotériques, donc je me demande s'il existe un sous-groupe de motifs "essentiels" que tous les programmeurs devraient connaître. En parcourant la liste, je pense que j'ai probablement utilisé -

  • Usine abstraite
  • Méthode d'usine
  • Singleton
  • Pont
  • Façade
  • Commander

Lesquels utilisez-vous réellement dans la pratique et à quoi les utilisez-vous?

Lien pour ceux qui veulent une liste de modèles

Craig Schwarze
la source
7
À mon humble avis, la question est trop vague pour permettre une discussion utile. Voulez-vous une réponse par modèle ou une réponse par combinaison de modèles?
Macke
Certaines raisons pour lesquelles vous utilisez ces modèles seraient utiles, sinon vous ne faites que lister des concepts ... Imaginez que vous posiez la question: "Quels mots clés utilisez-vous?" et la collecte de listes de " for, if, while...etc" - difficile à mesurer à quel point cela serait inutile.
ocodo
1
Je ne suis pas d'accord Slomojo - je pense qu'il serait très utile de savoir quels mots clés sont couramment utilisés et lesquels ne sont pas dans une langue. Il en va de même pour les classes de base, par exemple.
Craig Schwarze
1
Modifié un peu plus - j'espère que cela va générer une meilleure discussion maintenant.
Craig Schwarze
1
Quels fruits mangez-vous réellement? Je suis curieux de savoir ce que vous espérez retirer de cette question. Si vous voyez un modèle que 3 ou 4 personnes ont utilisé mais que vous ne l'avez pas fait, est-ce que cela vous incitera à l'utiliser?
Marcie

Réponses:

4

Voici une liste de ceux que j'ai utilisés ou vus dans la pratique:

Singleton - L'objet Application dans ASP.Net en est un excellent exemple.

Adaptateur - La connexion à des bases de données peut généralement impliquer une classe d'adaptateur au moins dans mon domaine .Net.

Usine - Général pour générer des objets, bien que j'aie vu cela plus dans certains ASP classiques plus anciens à l'époque.

Stratégie - J'avais une application qui, pour chaque type d'appareil, avait une structure similaire pour la classe que je considérerais comme une implémentation de ce modèle.

Façade - À certains égards, cela est similaire au modèle d'adaptateur en termes d'être quelque chose qui relie généralement quelques systèmes.

JB King
la source
1
Toutes les utilisations valides. Pour tous ceux qui lisent également ceci - gardez à l'esprit que ces modèles ne sont certainement pas limités à ceux-ci.
Boris Yankov
5

Les auteurs ont compilé les modèles à partir des conceptions observées qu'ils ont trouvées dans des applications réelles. Personne ne les utilisera probablement tous, mais ils sont tous utilisés.

smithco
la source
Lequel avez-vous utilisé smithco et pourquoi?
Craig Schwarze
@CraigS J'en ai utilisé beaucoup. Les auteurs de Design Patterns ont un ensemble de bons exemples avec chaque modèle qu'ils décrivent. La meilleure suggestion que je puisse donner est de passer du temps à lire attentivement le livre.
smithco
3

Décorateur .

EDIT : Dans presque tous les projets qui dépassent le stade «trivial», on se retrouve avec une interface IAction (les détails peuvent différer):

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

L'heure suivante, je passe à écrire de nombreuses petites classes presque triviales qui implémentent IAction. Lorsqu'ils sont combinés, ils sont très puissants et flexibles.

Par exemple an LogAction(écrire pour se connecter et effectuer l'IAction), NullAction(ne rien faire et retourner true), ActionList(effectuer une liste d'IActions, et retourner l'AND des bools). Dans certains cas , un AndAction(retourner le ET-ing de deux actions, pourrait être court-circuité ou non), OrAction, NotActionfaire sens aussi bien.

Bien que techniquement, à partir des exemples ci-dessus, seule la LogAction est un décorateur (les autres ne fonctionnent pas sur exactement 1 IAction), je considère toujours cela comme une généralisation du modèle Decorator lorsque je crée une ActionList of LogActions of IActions.

Sjoerd
la source
Qu'utilisez vous pour ça?
Craig Schwarze
1
@CraigS Exemple ajouté sur demande.
Sjoerd
Cela ressemble plus à un mélange de Decorator et Composite en fait, ce qui est bien, et une démonstration parfaite que la difficulté des motifs ne vient pas de les utiliser indépendamment, mais de les mélanger ensemble :)
Matthieu M.
Oui, c'est un classique. Il est composite avec commande. Il y a en fait un nom pour ce motif: il s'appelle "Specification" ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman
2

Je suppose que vous voulez restreindre la question à l'utilisation de modèles dans votre propre code / projets (pas de bibliothèques de classes et de cadres tiers).

Comme d'autres, j'ai également utilisé les modèles Factory le plus souvent. alors

  • Singleton : pas tellement de nos jours, mais il est parfois nécessaire, généralement pour les données de configuration globale
  • Stratégie et méthode de modèle : assez souvent, par exemple pour représenter différents types de calculs dans notre application
  • Builder : pour rassembler les résultats des transactions avec un système mainframe en objets de sortie (dans certains cas, il comprend une grande quantité d'analyse de texte et la création de grandes hiérarchies d'objets)
  • Commande : Je ne l'ai implémentée qu'une seule fois il y a de nombreuses années, mais de nos jours dans notre projet Java, j'utilise Callables de temps en temps, ce qui, à mon avis, sont essentiellement des commandes
Péter Török
la source
2

J'ai utilisé bon nombre des autres qui ont déjà été mentionnés (Singleton, Factory, Builder, Command, Strategy, etc ...)

Un que je n'ai pas encore vu mentionné est Flyweight, que j'ai tendance à utiliser beaucoup. J'ai fourni un exemple d'implémentation ci-dessous:

/**
 * 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
la source
1
+1 l'un des modèles les moins connus mais toujours incroyablement utiles.
MattDavey
2

La plupart des motifs originaux de Gang of Four sont toujours utilisés aujourd'hui, mais il y en a d'autres maintenant populaires qui ne figurent pas dans le livre.

Trouvez une référence pour Design Patters dans la langue que vous utilisez. Ils ont tendance à être plus concrets et à utiliser des fonctionnalités de langage spécifiques pour implémenter les modèles de manière plus succincte et élégante.

Trois excellentes ressources pour les modèles de conception:

Livre "Head First Design Patterns" - le langage de prédilection est Java, mais s'applique à tous les langages. dofactory Design Patterns - grandes et gratuites explications de modèles de conception .net avec du code. PluralSight - Design Patterns Library - celui-ci est payé, mais est trop bon pour ne pas l'inclure dans la liste.

Boris Yankov
la source
1

Eh bien, si vous utilisez des bibliothèques communes comme ACE, vous finissez par utiliser plus que vous ne pensez en utiliser. J'utilise largement Observer / Observable :-)

Geek
la source
1

J'ai utilisé un générateur au moins une fois (le même processus de conversion pourrait générer une sortie HTML ou Excel).

J'utilise fréquemment la méthode Template (pour les tâches liées à JDBC ou les contrôleurs Swing abstraits).

Une fois, j'ai dû développer de nombreuses nouvelles fonctionnalités dans une application basée sur un formulaire, ce qui était un gâchis. Je ne pouvais progresser qu'après avoir refactorisé les éléments existants vers une solution basée sur un modèle d'état. (Eh bien, la plupart du temps).

J'utilise également fréquemment des commandes (Swing Actions) et des observateurs.

Une fois, j'ai utilisé une solution de type Mememento pour détecter les changements dans les formulaires Swing. Le formulaire sérialiserait son état ce que j'ai comparé (égal ()) aux états précédents.

Karl
la source
1

Je crois que j'ai la plupart d'entre eux tout au long de ma carrière. le seul que je suis sûr que je n'ai pas utilisé est ce modèle d'adaptateur qui est implémenté avec l'héritage multiple sur le livre car je ne suis pas un grand fan de l'héritage multiple.

Raphael
la source
1

J'aime le décorateur. Le seul que j'ai ajouté à ceux mentionnés est le proxy.

Chuck Stephanski
la source