Patrones de diseño de GoF: ¿cuáles utilizas realmente? [cerrado]

16

Estoy tratando de educar a mis colegas en el área de patrones de diseño. Algunos de los patrones originales de Gang of Four son un poco esotéricos, por lo que me pregunto si hay un subgrupo de patrones "esenciales" que todos los programadores deben saber. Al mirar la lista, creo que probablemente he usado

  • Fábrica abstracta
  • Método de la fábrica
  • único
  • Puente
  • Fachada
  • Mando

¿Cuáles usas en la práctica y para qué las usas?

Enlace para aquellos que desean una lista de patrones

Craig Schwarze
fuente
77
En mi humilde opinión, la pregunta es demasiado vaga para generar una discusión útil. ¿Desea una respuesta por patrón o una respuesta por combinación de patrones?
Macke
Algunas razones por las que usa estos patrones serían útiles, de lo contrario, solo está enumerando conceptos ... Imagine hacer la pregunta: "¿Qué palabras clave usa?" y la recopilación de listas de " for, if, while...etc" - difícil de medir cuán inútil sería eso.
ocodo
1
No estoy de acuerdo con Slomojo: creo que sería bastante útil saber qué palabras clave se usan comúnmente y cuáles no están en un idioma. Lo mismo ocurre con las clases base, por ejemplo.
Craig Schwarze
1
Lo modifiqué un poco más, espero que esto genere una mejor discusión ahora.
Craig Schwarze
1
¿Qué tipo de fruta comes realmente? Tengo curiosidad por saber qué espera obtener de esta pregunta. Si ve un patrón que 3 o 4 personas han usado pero usted no, ¿eso lo hará usarlo?
Marcie

Respuestas:

4

Aquí hay una lista de los que he usado o visto en la práctica:

Singleton: el objeto de aplicación en ASP.Net es un excelente ejemplo de esto.

Adaptador: la conexión a bases de datos generalmente puede involucrar una clase de Adaptador al menos en mi área de cosas.

Factory - General para generar objetos, aunque lo vi más en algunos ASP clásicos más antiguos en el día.

Estrategia: tenía una aplicación que para cada tipo de dispositivo tenía una estructura similar para la clase que consideraría una implementación de este patrón.

Fachada: en algunos aspectos, esto es similar al patrón del Adaptador en términos de ser algo que generalmente une un par de sistemas.

JB King
fuente
1
Todos los usos válidos. Para cualquiera que también lea esto, tenga en cuenta que estos patrones ciertamente no se limitan a estos.
Boris Yankov
5

Los autores compilaron los patrones de los diseños observados que encontraron en aplicaciones reales. Es probable que ninguna persona los use a todos, pero todos se usan.

smithco
fuente
¿Para qué has usado smithco y para qué?
Craig Schwarze
@ CraigS He usado muchos de ellos. Los autores de Patrones de diseño tienen un conjunto de buenos ejemplos con cada patrón que describen. La mejor sugerencia que puedo dar es pasar el tiempo leyendo el libro a fondo.
smithco
3

Decorador .

EDITAR : en casi todos los proyectos que van más allá de la etapa 'trivial', uno termina con una interfaz IAction (los detalles pueden diferir):

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

La siguiente hora la paso escribiendo muchas clases pequeñas, casi triviales, que implementan IAction. Cuando se combinan, son muy potentes y flexibles.

Por ejemplo, an LogAction(escribir para iniciar sesión y realizar la IAction), NullAction(no hacer nada y devolver true), ActionList(realizar una lista de IActions y devolver el AND de los bools). En algunos casos, un AndAction(devolver el AND de dos acciones, podría estar en cortocircuito o no) OrAction, también NotActiontiene sentido.

Aunque técnicamente de los ejemplos anteriores, solo LogAction es un Decorador (el otro no funciona exactamente en 1 IAction), todavía considero que esto es una generalización del patrón Decorator cuando hago una Lista de Acciones de LogActions de IActions.

Sjoerd
fuente
Para que lo usas?
Craig Schwarze
1
@CraigS Ejemplo agregado a pedido.
Sjoerd
En realidad, se parece más a una mezcla de Decorador y Compuesto, lo cual está bien, y es una demostración perfecta de que la dificultad en los patrones no viene de usarlos de forma independiente, sino de mezclarlos juntos :)
Matthieu M.
Un sí, este es un clásico. Es compuesto combinado con comando. En realidad, hay un nombre para este patten: se llama "Especificación" ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman
2

Supongo que se refiere a restringir la pregunta al uso de patrones en código / proyectos propios (sin bibliotecas de clases y marcos de terceros).

Al igual que otros, también he usado los patrones Factory con mayor frecuencia. Luego

  • Singleton : no tanto hoy en día, pero a veces es necesario, generalmente para datos de configuración global
  • Estrategia y método de plantilla : con bastante frecuencia, por ejemplo, para representar diferentes tipos de cálculos en nuestra aplicación
  • Generador : para ordenar los resultados de transacciones con un sistema mainframe en objetos de salida (en algunos casos, incluye una gran cantidad de análisis de texto y la creación de jerarquías de objetos grandes)
  • Comando : lo implementé solo una vez hace muchos años, pero hoy en día en nuestro proyecto Java uso Callables de vez en cuando, lo que creo que son básicamente comandos
Péter Török
fuente
2

He usado muchos de los otros que ya se han mencionado (Singleton, Factory, Builder, Command, Strategy, etc.)

Uno que no he visto mencionado todavía es Flyweight, que tiendo a usar mucho. He proporcionado un ejemplo de implementación a continuación:

/**
 * 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
fuente
1
+1 uno de los patrones menos conocidos pero aún increíblemente útiles.
MattDavey
2

La mayoría de los patrones originales de Gang of Four todavía se usan hoy en día, pero hay otros ahora populares que no están en el libro.

Encuentre una referencia para Design Patters en el idioma que usa. Tienden a ser más concretos y utilizan características de lenguaje específicas para implementar los patrones de una manera más sucinta y elegante.

Tres excelentes recursos para patrones de diseño:

Libro "Head First Design Patterns" : el idioma de elección es Java, pero es relevante para todos los idiomas. Patrones de diseño dofactory : excelentes y gratuitas explicaciones de patrones de diseño .net con código. PluralSight - Biblioteca de patrones de diseño : esta se paga, pero es demasiado buena para no incluirla en la lista.

Boris Yankov
fuente
1

Bueno, si usa bibliotecas comunes como ACE, terminará usando más de lo que cree que usa. Yo uso Observador / Observable ampliamente :-)

Friki
fuente
1

Usé un Builder al menos una vez (el mismo proceso de conversión podría generar salida HTML o Excel).

Con frecuencia uso el Método de plantilla (para tareas relacionadas con JDBC o controladores abstractos Swing).

Una vez tuve que desarrollar muchas características nuevas en una aplicación basada en formularios, lo cual fue un desastre. Solo pude progresar después de haber refactorizado las cosas existentes a una solución basada en patrones estatales. (Bueno, la mayor parte).

También uso los comandos con frecuencia (acciones de oscilación) y los observadores también.

Una vez utilicé una solución tipo Mememento para detectar cambios en las formas de Swing. El formulario serializaría su estado de lo que comparé (igual ()) a estados anteriores.

Karl
fuente
1

Creo que tengo la mayoría de ellos a lo largo de mi carrera. El único que estoy seguro de que no he usado es ese Patrón de adaptador que se implementa con herencia múltiple en el libro, ya que no soy un gran fanático de la herencia múltiple.

Rafael
fuente
1

Soy aficionado a Decorator. El único que tengo que agregar a los mencionados es Proxy.

Chuck Stephanski
fuente