Padrões de design do GoF - quais você realmente usa? [fechadas]

16

Estou tentando educar meus colegas na área de padrões de design. Alguns dos padrões originais da Gangue dos Quatro são um pouco esotéricos, então estou me perguntando se existe um subgrupo de padrões "essenciais" que todos os programadores devem conhecer. Ao examinar a lista, acho que provavelmente já usei -

  • Fábrica abstrata
  • Método de fábrica
  • Singleton
  • Ponte
  • Fachada
  • Comando

Quais você realmente usa na prática e para que os usa?

Link para quem deseja uma lista de padrões

Craig Schwarze
fonte
7
IMHO, a pergunta é muito vaga para gerar uma discussão útil. Deseja uma resposta por padrão ou uma resposta por combinação de padrões?
27611 Macke
Algumas razões pelas quais você usa esses padrões seriam úteis, caso contrário, você está apenas listando conceitos ... Imagine fazer a pergunta: "Quais palavras-chave você usa?" e coleta de listas de " for, if, while...etc" - difícil de medir o quão inútil isso seria.
Ocodo 17/02
1
Discordo do Slomojo - acho que seria bastante útil saber quais palavras-chave eram comumente usadas e quais não estavam em um idioma. O mesmo vale para as classes base, por exemplo.
Craig Schwarze
1
Modificado um pouco mais - espero que isso gere uma discussão melhor agora.
Craig Schwarze
1
Que tipos de frutas você realmente come? Estou curioso para saber o que você espera obter dessa pergunta. Se você vir um padrão que 3 ou 4 pessoas usaram, mas você não usou, isso fará com que você o use?
Marcie

Respostas:

4

Aqui está uma lista de quais eu usei ou vi na prática:

Singleton - objeto de aplicativo no ASP.Net, sendo um excelente exemplo disso.

Adaptador - Conectar-se a bancos de dados geralmente pode envolver uma classe Adapter pelo menos na minha área de coisas .Net.

Fábrica - Geral para gerar objetos, embora eu tenha visto isso mais em alguns ASP clássicos mais antigos na época.

Estratégia - Eu tinha um aplicativo que, para cada tipo de dispositivo, tinha uma estrutura semelhante para a classe que consideraria uma implementação desse padrão.

Fachada - De certa forma, isso é semelhante ao padrão do adaptador em termos de algo que normalmente une alguns sistemas.

JB King
fonte
1
Todos os usos válidos. Para quem também estiver lendo isso - tenha em mente que esses padrões certamente não se limitam a eles.
Boris Yankov
5

Os autores compilaram os padrões dos desenhos observados encontrados em aplicações reais. É provável que ninguém use todos eles, mas todos eles são usados.

smithco
fonte
Para quem você usou o smithco e para quê?
Craig Schwarze
@ CraigS Eu usei muitos deles. Os autores de Design Patterns têm um conjunto de bons exemplos com cada padrão que descrevem. A melhor sugestão que posso dar é dedicar tempo à leitura completa do livro.
18711 smithco
3

Decorador .

EDIT : Em quase todos os projetos que ultrapassam o estágio 'trivial', um termina com uma interface IAction (os detalhes podem ser diferentes):

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

Na próxima hora, passo escrevendo muitas classes pequenas e quase triviais que implementam o IAction. Quando combinados, eles são muito poderosos e flexíveis.

Por exemplo, um LogAction(escreva para registrar e executar a IAction), NullAction(não faça nada e retorne true), ActionList(execute uma lista de IActions e retorne o AND dos bools). Em alguns casos, um AndAction(retornar o AND de duas ações, pode estar em curto-circuito ou não) OrAction, também NotActionfaz sentido.

Embora tecnicamente, a partir dos exemplos acima, apenas o LogAction seja um Decorator (o outro não opera exatamente com 1 IAction), ainda considero isso uma generalização do padrão Decorator quando faço uma ActionList de LogAtions de IActions.

Sjoerd
fonte
para que você usa isso?
Craig Schwarze
1
@CraigS Exemplo adicionado a pedido.
Sjoerd
Parece mais uma mistura de Decorator e Composite, na verdade, o que é bom, e uma demonstração cabal de que a dificuldade em padrões não vem de usá-los de forma independente, mas a partir de mistura-los juntos :)
Matthieu M.
Um sim, este é um clássico. É composto emparelhado com o comando. Na verdade, existe um nome para esse padrão: ele é chamado de "Especificação" ( en.wikipedia.org/wiki/Specification_pattern ).
Martin Wickman
2

Suponho que você pretenda restringir a pergunta ao uso de padrões em códigos / projetos próprios (sem bibliotecas de classes e estruturas de terceiros).

Como outros, também usei os padrões de fábrica com mais freqüência. Então

  • Singleton : não muito hoje em dia, mas ainda às vezes é necessário, geralmente para dados de configuração global
  • Estratégia e método de modelo : com bastante frequência, por exemplo, para representar diferentes tipos de cálculos em nosso aplicativo
  • Construtor : para organizar os resultados das transações com um sistema de mainframe em objetos de saída (em alguns casos, inclui uma grande quantidade de análise de texto e criação de grandes hierarquias de objetos)
  • Comando : eu o implementei apenas uma vez há muitos anos, mas hoje em dia em nosso projeto Java eu ​​uso Callables de vez em quando, o que acredito ser basicamente Comandos
Péter Török
fonte
2

Eu usei muitos dos outros que já foram mencionados (Singleton, Factory, Builder, Command, Strategy, etc ...)

Um que eu não vi mencionado ainda é o Flyweight, que eu costumo usar muito. Forneci um exemplo de implementação abaixo:

/**
 * 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
fonte
1
Marcar com +1 um dos padrões menos conhecidos, mas ainda incrivelmente úteis.
precisa saber é o seguinte
2

A maioria dos padrões originais da Gangue dos Quatro ainda é usada hoje em dia, mas existem outros agora populares que não estão no livro.

Encontre uma referência para Design Patters no idioma que você usa. Eles tendem a ser mais concretos e usam recursos específicos de linguagem para implementar os padrões de maneira mais sucinta e elegante.

Três ótimos recursos para Design Patterns:

Livro "Head First Design Patterns" - a linguagem de escolha é Java, mas é relevante para todas as linguagens. Padrões de Design dofactory - excelentes e gratuitas explicações sobre padrões de design .net com código. PluralSight - Design Patterns Library - este é pago, mas é bom demais para não incluí-lo na lista.

Boris Yankov
fonte
1

Bem, se você usa bibliotecas comuns como o ACE, acaba usando mais do que pensa. Eu uso o Observer / Observable extensivamente :-)

Nerd
fonte
1

Usei um construtor pelo menos uma vez (o mesmo processo de conversão pode criar saída em HTML ou Excel).

Eu freqüentemente uso o método de modelo (para tarefas relacionadas ao JDBC ou controladores Swing abstratos).

Uma vez eu tive que desenvolver muitos novos recursos em um aplicativo baseado em formulário, o que foi uma bagunça. Eu só consegui progredir depois de refatorar o material existente para uma solução baseada em padrão de estado. (Bem, a maioria).

Eu também uso Comandos frequentemente (Ações de Swing) e Observadores também.

Uma vez eu usei uma solução semelhante a Mememento para detectar alterações nas formas Swing. O formulário serializaria seu estado com o que eu comparei (equals ()) com estados anteriores.

Karl
fonte
1

Acredito que os tenho ao longo da minha carreira. o único que tenho certeza de que não usei é o Padrão de Adaptador implementado com herança múltipla no livro, pois não sou um grande fã de herança múltipla.

Rafael
fonte
1

Eu gosto de Decorator. O único que tenho adicionado aos mencionados é Proxy.

Chuck Stephanski
fonte