GoF Design Patterns - quali usi effettivamente? [chiuso]


16

Sto cercando di educare i miei colleghi nell'area dei modelli di progettazione. Alcuni dei modelli originali Gang of Four sono un po 'esoterici, quindi mi chiedo se ci sia un sottogruppo di pattern "essenziali" che tutti i programmatori dovrebbero conoscere. Mentre guardo l'elenco, penso di aver probabilmente usato -

  • Fabbrica astratta
  • Metodo di fabbrica
  • Singleton
  • ponte
  • Facciata
  • Comando

Quali usi effettivamente in pratica e per cosa li usi?

Link per chi desidera un elenco di modelli


7
IMHO, la domanda è troppo vaga per dare utili discussioni. Vuoi una risposta per modello o una risposta per combinazione di modelli?
Macke,

Alcuni motivi per cui usi questi schemi sarebbero utili, altrimenti stai solo elencando concetti ... Immagina di porre la domanda: "Quali parole chiave usi?" e raccogliere elenchi di " for, if, while...etc" - difficile misurare quanto sarebbe inutile.
ottobre

1
Non sono d'accordo Slomojo - penso che sarebbe abbastanza utile sapere quali parole chiave erano comunemente usate e quali non erano in una lingua. Lo stesso vale per le classi di base, ad esempio.
Craig Schwarze,

1
Modificato un po 'di più - speriamo che questo generi qualche discussione migliore ora.
Craig Schwarze,

1
Che tipo di frutta mangi effettivamente? Sono curioso di sapere cosa speri di uscire da questa domanda. Se vedi uno schema che 3 o 4 persone hanno usato ma non l'hai fatto, questo ti farà usare?
Marcie,

Risposte:


4

Ecco un elenco di quelli che ho usato o visto in pratica:

Singleton - L'oggetto applicazione in ASP.Net ne è un ottimo esempio.

Adapter - La connessione ai database di solito può comportare una classe Adapter almeno nella mia area di cose .Net.

Factory - Generale per la generazione di oggetti, anche se l'ho visto di più in alcuni vecchi ASP classici di altri tempi.

Strategia - Avevo un'applicazione che per ogni tipo di dispositivo avevo una struttura simile per la classe che avrei considerato un'implementazione di questo modello.

Facciata - In un certo senso è simile al modello dell'adattatore in termini di essere qualcosa che lega di solito un paio di sistemi.


1
Tutti gli usi validi. Per chiunque legga anche questo, tieni presente che questi schemi non sono certamente limitati a questi.
Boris Yankov,

5

Gli autori hanno compilato i modelli dai disegni osservati che hanno trovato in applicazioni reali. Probabilmente nessuno li utilizzerà tutti, ma sono tutti usati.


Per chi hai usato smithco, e per cosa?
Craig Schwarze,

@CraigS Ne ho usati molti. Gli autori di Design Patterns hanno una serie di buoni esempi con ogni modello che descrivono. Il miglior suggerimento che posso dare è di passare il tempo a leggere il libro a fondo.
smithco,

3

Decorator .

EDIT : in quasi tutti i progetti che vanno oltre la fase "banale", si finisce con un'interfaccia IAction (i dettagli possono differire):

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

L'ora successiva trascorro a scrivere molte piccole classi quasi banali che implementano IAction. Se combinati, sono molto potenti e flessibili.

Ad esempio un LogAction(scrivere per registrare ed eseguire l'IAction), NullAction(non fare nulla e restituire true), ActionList(eseguire un elenco di IActions e restituire l'ANDing dei bool). In alcuni casi un AndAction(restituire il E-zione di due azioni, potrebbe essere in corto circuito o no), OrAction, NotActionha senso pure.

Sebbene tecnicamente dagli esempi sopra solo LogAction sia un Decorator (l'altro non funziona esattamente su 1 IAction), considero comunque una generalizzazione del modello Decorator quando realizzo una ActionList di LogActions of IActions.


Per cosa lo usi?
Craig Schwarze,

1
@CraigS Esempio aggiunto su richiesta.
Sjoerd,

Sembra più un mix di Decorator e Composite in realtà, il che va bene, e una dimostrazione perfetta che la difficoltà nei motivi non deriva dal loro uso indipendente, ma dal mescolarli insieme :)
Matthieu M.

A sì, questo è un classico. È composto da comando. In realtà c'è un nome per questo patten: si chiama "Specification" ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman,

2

Presumo che tu intenda limitare la domanda all'utilizzo dei pattern nel proprio codice / progetto (nessuna libreria di classi e framework di terze parti).

Come altri, ho usato spesso anche i modelli Factory . Poi

  • Singleton : non tanto al giorno d'oggi, ma a volte è ancora necessario, in genere per i dati di configurazione globali
  • Metodo di strategia e modello : abbastanza spesso, ad esempio per rappresentare diversi tipi di calcoli nella nostra app
  • Builder : per il marshalling dei risultati delle transazioni con un sistema mainframe in oggetti di output (in alcuni casi include una grande quantità di analisi del testo e la creazione di grandi gerarchie di oggetti)
  • Comando : l'ho implementato solo una volta molti anni fa, ma oggigiorno nel nostro progetto Java utilizzo di tanto in tanto Callables, che credo siano fondamentalmente comandi

2

Ho usato molti degli altri che sono già stati menzionati (Singleton, Factory, Builder, Command, Strategy, ecc ...)

Uno che non ho ancora visto menzionato è Flyweight, che tendo a usare molto. Ho fornito un'implementazione di esempio di seguito:

/**
 * 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) : "?";
    }
}

1
+1 uno dei modelli meno conosciuti ma ancora incredibilmente utili.
MattDavey,

2

La maggior parte dei modelli originali Gang of Four sono ancora usati oggi, ma ce ne sono altri ormai popolari che non sono nel libro.

Trova un riferimento per Design Patters nella lingua che usi. Tendono ad essere più concreti e usano caratteristiche linguistiche specifiche per implementare gli schemi in modo più conciso ed elegante.

Tre grandi risorse per i design pattern:

Libro "Head First Design Patterns" - la lingua scelta è Java, ma è rilevante per tutte le lingue. Dofactory Design Patterns - spiegazioni fantastiche e gratuite di schemi di progettazione .net con codice. PluralSight - Design Patterns Library - questo è a pagamento, ma è troppo bello per non includerlo nell'elenco.


1

Bene, se usi librerie comuni come ACE, finisci per usare più di quanto pensi di usare. Uso ampiamente Observer / Observable :-)


1

Ho usato un Builder almeno una volta (lo stesso processo di conversione potrebbe generare output HTML o Excel).

Uso frequentemente il metodo Template (per attività relative a JDBC o controller Swing astratti).

Una volta ho dovuto sviluppare molte nuove funzionalità in un'applicazione basata su form, che era un casino. Ho potuto progredire solo dopo aver eseguito il refactoring delle cose esistenti in una soluzione basata sullo schema statale. (Beh, la maggior parte di esso).

Uso anche i Comandi frequentemente (Swing Actions) e anche gli osservatori.

Una volta ho usato una soluzione simile a Mememento per rilevare i cambiamenti nelle forme Swing. Il modulo serializzerebbe il suo stato con quello che ho confrontato (uguale a) agli stati precedenti.


1

Credo di averne quasi tutti in carriera. l'unico che sono sicuro di non aver usato è quel modello di adattatore che è implementato con ereditarietà multipla sul libro poiché non sono un grande fan dell'ereditarietà multipla.


1

Sono appassionato di Decorator. L'unico che ho aggiunto a quelli menzionati è Proxy.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.