Para cada projeto de programação, gerentes com experiência anterior em programação tentam brilhar quando recomendam alguns padrões de design para o seu projeto. Gosto de padrões de design quando eles fazem sentido ou se você precisar de uma solução escalável. Eu usei padrões de Proxies, Observadores e Comando de uma maneira positiva, por exemplo, e faço isso todos os dias. Mas estou realmente hesitante em usar o padrão Factory, se houver apenas uma maneira de criar um objeto, pois uma fábrica pode facilitar tudo no futuro, mas complica o código e é pura sobrecarga.
Portanto, minha pergunta é em relação à minha futura carreira e minha resposta aos tipos de gerente que usam nomes aleatórios de padrões:
Quais padrões de design você usou que o levaram de volta no geral? Quais são os piores padrões de design , os que você deve considerar, exceto na única situação em que eles fazem sentido (leia-se: quais padrões de design são definidos de maneira muito restrita)? (É como se eu estivesse procurando as críticas negativas de um bom produto geral da Amazon para ver o que mais incomodava as pessoas ao usar padrões de design.) E não estou falando sobre Anti-Patterns aqui, mas sobre padrões que geralmente são considerados padrões "bons".
Edit: Como alguns responderam, o problema geralmente é que os padrões não são "ruins", mas "usados incorretamente". Se você conhece padrões, que são frequentemente mal utilizados ou mesmo difíceis de usar, eles também serviriam como resposta.
Respostas:
Não acredito em maus padrões, acredito que os padrões podem ser mal aplicados!
Para esta resposta, considerei apenas os padrões GOF. Não conheço todos os padrões possíveis o suficiente para levá-los em consideração também.
fonte
Além de Singleton e Visitor já mencionados pelos outros respondentes, não conheço padrões de design "notórios". IMHO, os maiores problemas não decorrem de um padrão de design específico estar "errado", mas de desenvolvedores que aplicam padrões com muita avidez.
Quase todo mundo passa pela fase da "febre do padrão" ao se familiarizar com os padrões. Pensando que os padrões são a melhor coisa desde o pão fatiado, inicialmente tenta-se aplicá-los sempre que vê uma possibilidade. Isso faz com que o código fique oculto sob padrões, onde os próprios padrões não ajudam mais, apenas tornam o código mais difícil de entender e manter a longo prazo.
Eventualmente, a maioria de nós supera essa fase e começa a aprender como usar os padrões para resolver problemas reais, não por eles mesmos. Os padrões têm seu preço, que é uma complexidade adicionada, e a aplicação de qualquer padrão específico só é justificada quando se paga pela complexidade adicionada, ajudando a simplificar alguma outra parte do sistema, tornando assim o código / configuração geral mais fácil de entender e manter. Se não for esse o caso, geralmente é melhor ficar longe dos padrões, mantendo a solução mais simples que possa funcionar.
fonte
Eu vou sair em um galho aqui e sugerir o uso excessivo de herança. Definitivamente, o mais aplicável em linguagens sem suporte sólido ao polimorfismo em tempo de compilação, como Java. A herança em tempo de execução é uma ferramenta, não um tipo de maravilha de um recurso para todos.
Outras pessoas já expressaram similar ao meu ódio pessoal a Singletons, então não vou expandir isso aqui.
fonte
Singleton. É um dos padrões GOF que agora é chamado com mais frequência como antipadrão. Uma das razões para isso é que Singleton torna o código mais difícil de testar.
fonte
:-)
Seguindo o padrão MVVM para WPF muito estritamente, como indicado, por exemplo, por esta pergunta . Algumas pessoas tentam seguir a diretriz de que nenhum código deve ser colocado no código por trás de maneira muito rigorosa e criar todo tipo de hacks exóticos.
E, é claro, o MVVM é difícil como o inferno, e não vale a pena para pequenos projetos de curto prazo.
O Dr. WPF fez um post irônico sobre isso em seu artigo MV-poo .
fonte
Alguns dos padrões no livro GOF são específicos para C ++, no sentido em que são menos aplicáveis em linguagens com reflexão, por exemplo, o padrão Prototype é menos significativo em Java.
Considero o padrão do intérprete um padrão "estreito". Você precisa ter um problema geral que valha a pena desenvolver um solucionador de problemas geral. Ele funciona apenas para problemas especiais para os quais você pode inventar um idioma, definir uma gramática e escrever um intérprete. As instâncias do problema devem ser representáveis como uma sentença na gramática. Eu não acho que você se depara com essas situações com frequência.
fonte
O que mais me arrependo (embora não com mais veemência): Quando deveria ter criado uma função, mas implementei uma solução OOP.
fonte
Fábrica. Eu vi código implementá-lo que cria apenas um tipo. Isso é código totalmente inútil IMO. Não ajuda que muitos dos exemplos online sejam completamente inventados. Fábrica de pizza?
Talvez a fábrica seja mais fácil de testar devido à injeção de dependência. Mas adicionar esse código quando você não precisa, não faz sentido para mim, e o argumento de teste desaparece quando você pode usar estruturas simuladas como o JMockit. Quanto mais simples você puder criar um programa, melhor. As fábricas realmente só fazem sentido com um número maior de tipos (por maiores, quero dizer, pelo menos, mais de 2).
fonte
Singleton
Eu concordo com os outros sobre Singleton. Não que você nunca deva usá-los, apenas que isso se limite a muito poucos casos. Eles são usados como globais preguiçosos a maior parte do tempo.
A segurança de threads é um problema nos singletons. O tratamento de exceções é outro - se o singleton não conseguir criar corretamente - nem sempre você sabe se pode detectar o erro com segurança, principalmente se esse foi um desses objetos criados "antes do main". E depois há a questão da limpeza depois.
Costumo preferir usar um singleton e fazer com que todos os outros "wannabe" singletons "se inscrevam" no seu. Meu uso mais comum de singleton é o manuseio de "evento de grito": você apenas "transmite ao mundo" que um evento ocorreu e qualquer pessoa que esteja ouvindo que lida com o evento o faz. Dessa forma, você dissocia os eventos realmente acontecendo com o que os está ouvindo. (Registro, sinais, etc.)
Visitante
A coisa feia que eu acho sobre isso, além do fato de que os desenvolvedores não conseguem pensar em nomes significativos e apenas chamar os métodos visit (), é que ele adiciona extensibilidade em uma direção enquanto remove em outra, ou seja, adiciona funcionalidade extra, mas restringe o número de objetos que seus visitantes precisam saber sobre todos os tipos de objetos que podem visitar.
É possível, embora confuso, permitir a extensão nas duas direções, mas isso não usa totalmente o padrão de visitante em sua forma regular. O aplicativo mais comum para isso é a impressão de objetos: você tem diferentes maneiras de imprimir e diferentes objetos que precisam ser impressos. Você deve estender isso nas duas direções. (Impressão significa qualquer tipo de transformação de objetos em um fluxo: armazenamento em um arquivo / gravação em um console / GUI ... etc).
(Nota: você não deve confundir isso com a arquitetura de exibição de documento, que é um padrão ligeiramente diferente).
fonte
Penso que o problema com alguns dos padrões mais complexos é que existem tantas variações neles que perdem muito do seu valor como dispositivo de comunicação.
O pior infrator que consigo pensar nesta categoria é o padrão MVC. Mesmo se ignorarmos o MVP, há tantas variações nas funções de cada um desses itens que você precisará gastar uma hora em cada nova estrutura para descobrir onde estão os limites.
fonte
Não existem padrões ruins, apenas pessoas ruins.
Prefiro herdar código facilmente legível que faz algo claro, mas é um pouco detalhado ou não (fila de músicas vilãs do mal) reutilizável (suspiro!) Do que um misto de mistura
InheritAbstractTemplateFaucetSink<Kitchen>
.Código reutilizável é ótimo! Provavelmente, você não está escrevendo um código que será reutilizado ou reescrevendo uma lógica semelhante para outro aplicativo que levaria menos tempo do que uma tentativa insana de reutilizar o código de outro aplicativo.
Para uma leitura mais aprofundada, abra parte do código C nas implementações sãs dos cabeçalhos posix ou dos clibs e toque no padrão. Este código foi escrito por alguns dos programadores mais inteligentes e dedicados do mundo. Você sabe quantos padrões abstratos de fábrica você verá? ... NENHUM!. As chances são ainda melhores, se você entender as outras partes do que está acontecendo, encontrará a lógica muito fácil de entender e rastrear.
Meu argumento é que a maioria dos "padrões" não foram criados para melhorar o código, eles foram criados para vender livros e software de modelagem. Se você é bom em programação, provavelmente evitará a maioria deles e escreverá um código claro, conciso e inteligentemente projetado que resolve o seu problema. Quando você tiver outro problema, escreverá um código claro, conciso e inteligentemente projetado para resolver esse problema. Se seu objetivo é escrever menos código do que eu pensaria, você não seria um programador. Adoro escrever código e quero escrevê-lo o máximo possível. Quando reescrevo algo que já escrevi, faço isso dez vezes mais rápido e me livre de todas as coisas que não fiquei feliz com a primeira vez que fiz.
Com isso, deixarei você com provavelmente a melhor citação (relevante) em ciência da computação.
" Existem duas maneiras de construir um design de software: uma maneira é tornar tão simples que obviamente não há deficiências, e a outra maneira é torná-lo tão complicado que não há deficiências óbvias. O primeiro método é muito mais difícil. . "
fonte
Definitivamente, concordo que existe um tempo para a maioria dos padrões e que você pode abusar de muitos padrões. Sei que o que mais abusou no passado é o padrão Abstract Template. Levado ao máximo, é conhecido como webforms do ASP.NET.
fonte