Escolhendo o padrão de design certo

32

Eu sempre reconheci a importância de utilizar padrões de design. Estou curioso para saber como outros desenvolvedores escolhem o mais apropriado. Você usa uma série de características (como um fluxograma) para ajudá-lo a decidir?

Por exemplo:

Se os objetos estão relacionados, mas não queremos especificar classe concreta, considere Resumo

Quando a instanciação for deixada para classes derivadas, considere Factory

Precisa acessar elementos de um objeto agregado sequencialmente, tente o Iterator

ou algo parecido?

Carl sagan
fonte
8
Qual você acha que é a importância? programmers.stackexchange.com/questions/70877/…
pdr 6/02/02
Eu acho que a importância está na capacidade de reconhecer o padrão mais apropriado e holístico, para poder finalmente comunicar isso a outros desenvolvedores. Se isso faz sentido?
Carl Sagan
Eu concordo com @pdr. Penso no que preciso fazer, e lembrar o nome do padrão me ajuda a nomear a Classe para que outras pessoas saibam o que faz também.
precisa
4
De fato. Isso pode ser simplesmente resumido em "Como você escolhe o design certo?". Primeiro, não há um design certo , apenas muitos errados. Além disso, ele vem com experiência em pilhas (escolhendo as erradas).
Telastyn

Respostas:

109

Um equívoco chave no mundo atual de codificação é que os padrões são componentes básicos. Você pega um AbstractFactoryaqui e um Flyweightali e talvez um Singletonali e os conecta com XML e pronto, você tem um aplicativo em funcionamento.

Eles não são.

Hmm, isso não era grande o suficiente.

Padrões não são blocos de construção

Isso é melhor.

Um padrão é algo que você usa quando descobre que tem um problema - você precisa de alguma flexibilidade que o padrão fornece ou que você encontrou quando está criando um pouco de linguagem no arquivo de configuração e diz "espere um momento, pare, este é o seu próprio intérprete que estou escrevendo - esse é um problema conhecido e resolvido, use um padrão de intérprete ".

Mas observe que é algo que você descobre em seu código, não algo que você começa. Os criadores do Java não disseram "Oh, vamos colocar um Flyweight no número inteiro" no início, mas perceberam um problema de desempenho que poderia ser resolvido por um flyweight .

E, portanto, não existe um "fluxograma" usado para encontrar o padrão certo. O padrão é uma solução para um tipo específico de problema que foi encontrado repetidamente e as principais partes dele foram destiladas em um Padrão.

Começar com o padrão é como ter uma solução e procurar um problema. Isso é uma coisa ruim: leva a excesso de engenharia e, finalmente, à inflexibilidade no design.

Enquanto você escreve código, quando percebe que está escrevendo uma fábrica, pode dizer "ah ha! Isso é uma fábrica que estou prestes a escrever" e usar seu conhecimento para conhecer o padrão da fábrica para escrever rapidamente a próxima parte da código sem tentar redescobrir o padrão de fábrica. Mas você não começa com "Eu tenho uma aula aqui, vou escrever uma fábrica para ela, para que seja flexível" - porque não será.

Aqui está um trecho de uma entrevista com Erich Gamma (de Gamma, Helm, Johnson e Vissides ): Como usar padrões de design :

Tentar usar todos os padrões é uma coisa ruim, porque você terminará com designs sintéticos - designs especulativos que têm flexibilidade que ninguém precisa. Atualmente, o software é muito complexo. Não podemos dar ao luxo de especular o que mais deveria fazer. Precisamos realmente focar no que ele precisa. É por isso que gosto de refatorar padrões. As pessoas devem aprender que, quando têm um tipo específico de problema ou cheiro de código, como as pessoas chamam hoje em dia, podem ir à caixa de ferramentas de padrões para encontrar uma solução.


A melhor ajuda para o "o que usar, quando" é provavelmente a página da Wikipedia para o padrão de design de software - a seção "Classificação e lista" descreve a categoria em que cada padrão está e o que faz. Não há fluxograma; a descrição provavelmente é a melhor que você encontrará como um pequeno trecho de "o que usar quando".

Observe que você encontrará padrões diferentes em diferentes áreas da programação. O design da web possui seu próprio conjunto de padrões, enquanto o JEE (não o design da web) possui outro conjunto de padrões. Os padrões para programação financeira são completamente diferentes daqueles para o design da interface do usuário do aplicativo independente.

Portanto, qualquer tentativa de listar todas elas é inerentemente incompleta. Você encontra um, descobre como usá-lo e, eventualmente, torna-se uma segunda natureza e não precisa pensar em como ou quando usá-lo novamente (até que alguém lhe peça uma explicação).

Robert Harvey
fonte
11
+1 em "solução procurando um problema". Conhecer os padrões permitirá que você pule a descoberta natural deles quando for necessário resolver um problema que eles resolvem. Aprender sobre eles provavelmente ajudará a melhorar suas habilidades de codificação e design, da mesma maneira que a leitura do código de outras pessoas ou a aprendizagem de outra linguagem de programação. Mas você definitivamente não deve estar tentando ativamente "ajustar padrões" ao seu código.
gregmac
1
Eu sempre recomendo que os desenvolvedores comecem a examinar os padrões para se familiarizarem primeiro com os princípios de design. Todo padrão é uma ilustração de alguns dos princípios de design (o conjunto de princípios 'SOLID' é apenas um exemplo).
ryscl
2
Talvez você adicione um decorador e uma fachada a um aplicativo ;-) Dito de outra maneira, o objetivo dos padrões de design é nos dar um nome, uma linguagem comum ao discutir o que estamos construindo. É uma abreviação de uma pilha de conhecimentos de desenvolvimento conquistados com muito esforço.
EBarr
2
Lendo nas entrelinhas aqui, as etapas para escolher um padrão de design: 1. Sempre pense criticamente em qualquer código no qual você esteja trabalhando. 2. Abstraia o código específico em um problema básico 3. Esse problema tem uma solução conhecida (padrão de design )? 4. Sim, como faço para aplicar essa solução aos meus detalhes? 5. Adapte a solução genérica ao problema abstrato, para criar uma solução para o seu problema específico.
29414 Chris
@ Chris, que realmente resume tudo. Também não há nada de errado em escrevê-lo sem padrões e refatorar o código no padrão apropriado, se o design precisar.
18

Eu me pergunto:

  1. Que problema estou tentando resolver?
  2. Qual padrão de design de software (se houver) resolve mais de perto o mesmo problema ou fornece um caminho lógico para resolver meu problema?
  3. Preciso da abstração (e complexidade) adicional que o padrão fornece, ou é um excesso de engenharia para o meu problema específico? O problema pode ser resolvido de maneira mais simples e eficiente sem o padrão?

O processo de escolha de um padrão de software não é diferente do processo de escolha de uma estrutura de dados, exceto que, ao escolher uma estrutura de dados, você avalia as características de desempenho e memória do seu problema e escolhe a estrutura de dados que melhor se encaixa nessas características.

Robert Harvey
fonte
Claro, isso é algo sobre experiência e especialista, em vez de um plano ou fluxograma, e eu concordo com você. Mas deve haver algum uso de recursos completos, como uma folha de dicas avançada na qual foi categorizada, pelo menos no caso dos padrões mais importantes e frequentes, como fábrica, etc. Estou atrás de coisas como as situações recomendadas mais conhecidas em qual seria melhor usar um padrão. você conhece esse recurso na internet ?!
Pmpr 28/05
3
@Trix: sourcemaking.com/design_patterns
Robert Harvey