Padrões sempre existiram nas práticas de codificação de software. Eles eram idealizados e implantados em cada equipe de desenvolvimento, sempre que algum caso de sucesso era identificado e reproduzido em outros projetos. Porém existem alguns padrões específicos que tem sido identificados ao longo do tempo e que foram catalogados e amplamente disseminados e consagrados na comunidade de software, como os célebres Padrões de Projeto.

Um dos mais famosos catálogos de Design Patterns é o catálogo de padrões do GoF (Gang of Four), grupo com os quatro autores do livro “Design Patterns: Elements of Reusable Object-Oriented Software” (1995), que atribuiu popularidade aos conceitos de padrões de projeto. Outro catálogo denominado GRASP (General Responsibility Assignment Software Patterns), foi proposto por Larman em seu livro “Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development” (2005), e também foi muito importante para a comunidade de software, levando também em conta princípios de desenvolvimento como SOLID.
Um padrão de projeto pode ser identificado sempre que alguma prática de solução de problemas é resolvida de maneira semelhante em diferentes ambientes e equipes de desenvolvimento. Para propor algum padrão de projeto, é necessário identificar 3 critérios muito importantes: o nome do padrão, o problema que o padrão se propõe a resolver, e a forma com que o padrão se propõe a resolver o problema. Alguns autores também se preocupam em definir quando usar e consequencias de usar um determinado padrão de projeto, mas em linhas gerais um padrão de projeto deve ser específico o suficiente para responder ao problema independente de linguagem ou arquitetura.
Os padrões de projeto se tornaram tão relevantes para a comunidade de software, que começaram a orientar a construção de inúmeros projetos ao redor do mundo, inclusive a construção de algumas linguagens de programação, componentes e frameworks de desenvolvimento que temos hoje. A definição de conceitos como padrões de arquitetura, também contribuiu muito para isso, visto que ofereceram a grandes projetos, modelos de arquitetura compostos por diferentes padrões de desenvolvimento reunidos e combinados.

Um problema porém ainda permanece, desenvolver software preocupado com os padrões de projeto ainda é uma tarefa extremamente desafiadora, e que exige um alto grau de experiência e conhecimento de Orientação a Objetos. Como adotar os diversos princípios e leis da Orientação a Objetos, juntamente com os diversos padrões de desenvolvimento? Esta é uma pergunta difícil de se responder, principalmente porque os padrões, diferente das leis e princípios, não vem como uma simples cartilha de como programar, mas vem como uma proposta específica para um problema específico.
Nesse contexto, ressaltamos que conhecer os problemas e aprender a identifica-los ao longo do processo de desenvolvimento, é a chave para começar a demonstrar o real interesse em trabalhar com padrões de projeto. Quando um problema no projeto é identificado e compreendido de forma clara, propor uma solução ideal se torna uma tarefa bem mais objetiva. Se para cada problema de implementação encontrado for possível encontrar um padrão de projeto que solucione o problema, será necessário apenas adaptar a proposta ao projeto, e implementar a solução para resolver o problema.

Martin Fowler catalogou alguns dos principais problemas de implementação de código, chamando-os de code smells ou bad smells (maus cheiros), por servirem como sintomas para as necessidades de refatoração no código e no projeto. Não existe uma relação exata entre um padrão de projeto e um bad smell específico. Mas os padrões de projeto podem ser utilizados de diferentes maneiras, para resolver problemas específicos e contribuir para eliminar alguns dos maus cheiros do código. Isso acontece porque os padrões de projeto possuem foco em problemas específicos, mas apesar disso eles possuem uma base muito forte em leis e princípios de Orientação de Objetos que apontam soluções claras de implementação e como evitar problemas de código.
Cabe a cada equipe de software escolher e desenvolver práticas que agucem a percepção dos desenvolvedores a fim de identificar os problemas mais acertivamente, e nada como a prática diária de desenvolvimento para adquirir esse tipo de experiência.