Desenvolvimento - C#
Design Pattern: As Long As It Can Be
Um Design Pattern pode ser descrito como uma solução para um problema em um determinado contexto.
por Guilherme Bacellar MoralezNão me refiro ao planejamento, documentação e processos de um sistema, mas, ao comportamento de sentar e codificar (seja em um projeto inteiro ou em uma tarefa), pois torna-se extremamente oneroso quando começamos a nos referir a correções, atualizações e eventuais manutenções.
Mas, afinal, o que são Design Patterns?
Design Pattern
Um Design Pattern pode ser descrito como uma solução para um problema em um determinado contexto.
Em termos de orientação a objetos, Design Patterns identificam classes, instâncias, seus papéis, colaborações e a distribuição de responsabilidades. Seriam, então, descrições de classes e objetos que se comunicam, que são implementados a fim de solucionar um problema comum em um contexto específico.
Eles representam experiências e conhecimentos adquiridos, e que podem (e devem) ser compartilhados entre os desenvolvedores de software.
Em linhas gerais podemos dizer que: "Os Design Patterns são uma forma de colocar ordem no caos, identificando o que constantemente se repete nas mais diversas configurações de software. Sendo assim, reduzem substancialmente a quantidade de entropia relacionada aos problemas que podem surgir em um determinado projeto."
Podem ainda ser considerados como micro-arquitetura, contribuindo assim para a arquitetura final da solução.
Tipos de Design Pattern
Existem ao todo 23 Design Patterns que podem ser separadas em 3 tipos distintos (CSB):
- Creational (Criacional) - Define a configuração e inicialização de objetos e classes:
- Abstract Factory - Provê uma interface para a criação de famílias de objetos correlatos ou dependentes sem a necessidade de especificar a classe concreta destes objetos.
- Builder - Isola a construção de um objeto complexo de sua representação, de forma que o mesmo processo de construção possa ser capaz de criar diferentes representações.
- Factory Method - Define uma interface para a criação de objetos, mas deixa as sub-classes decidirem qual classe irão instanciar. O Factory Method permite que uma classe transfira para as sub-classes a responsabilidade pela criação de novas instâncias.
- Prototype - Especifica o tipo de objeto a criar através de uma instância protótipo e cria novos objetos através da cópia deste protótipo.
- Singleton - O objetivo deste padrão é garantir que uma classe possua apenas uma única instância e para tal, fornece um ponto global de acesso para a mesma.
- Abstract Factory - Provê uma interface para a criação de famílias de objetos correlatos ou dependentes sem a necessidade de especificar a classe concreta destes objetos.
- Structural (Estrutural) - Lida com as interfaces e a implementação das classes e dos objetos:
- Adapter - Converte a interface de uma classe em outra interface que os clientes esperam. O padrão Adapter permite que classes que não poderiam trabalhar juntas devido a interfaces incompatíveis trabalhem juntas.
- Bridge - Desacopla uma abstração de sua própria implementação de forma que as duas possam mudar de forma independente.
- Composite - Compõe objetos em estrutura de árvore para representar hierarquias do tipo todo-parte. Este padrão permite que as classes cliente tratem os objetos individuais e as composições de maneira uniforme.
- Decorator - Atribui, dinamicamente, responsabilidades a outros objetos.
- Facade - Uma única classe representando todo um subsistema.
- Flyweight - Uma instância refinada, utilizada para compartilhamento eficiente.
- Proxy - Um objeto que representa outro objeto.
- Adapter - Converte a interface de uma classe em outra interface que os clientes esperam. O padrão Adapter permite que classes que não poderiam trabalhar juntas devido a interfaces incompatíveis trabalhem juntas.
- Behavioral (Comportamental) - Lida com as interações dinâmicas entre grupos de classes e objetos
- Chain of Responsibility - Uma forma de passar requisições por uma cadeia de objetos.
- Command - Encapsular uma solicitação de comando na forma de um objeto.
- Interpreter - Uma forma de incluir elementos de linguagem num programa.
- Iterator - Acessa seqüencialmente os elementos de uma coleção.
- Mediator - Define uma comunicação simplificada entre classes.
- Memento - Captura e restaura o estado interno de um objeto.
- Observer - Uma forma de notificar mudanças efetuadas em uma certa quantidade de classes.
- State - Altera o comportamento de um objeto quando seu estado muda.
- Strategy - Encapsula um algoritmo dentro de uma classe.
- Template Method - Atribui cada passo de um algoritmo para uma subclasse.
- Visitor - Define uma nova operação para uma classe sem mudá-la.
- Chain of Responsibility - Uma forma de passar requisições por uma cadeia de objetos.
Algumas das vantagens visíveis da utilização de Design Patterns são:
- A utilização de Design Patterns força uma forma otimizada e clara de comunicação entre os desenvolvedores, documentação e maiores possibilidades de exploração para alternativas de soluções para o projeto.
- Melhora na qualidade geral do programa, pois reduz a complexidade do código oferecendo uma abstração das classes e instâncias.
- Redução no tempo de aprendizado de novas bibliotecas ou funções.
Porém, existem desvantagens obvias de sua utilização:
- A adoção tardia de Design Patterns pode tornar sua implementação mais custosa em prazos e custos, portanto, quanto mais cedo a definição dos Patterns ocorrer, melhor.
- Os patterns podem ser difíceis de implementar (em um primeiro momento, principalmente durante sua curva de aprendizado) e geralmente implicam na adoção de outros Patterns, mas, os resultados são sempre bem expressivos com relação à qualidade e versatilidade.
Anti-Pattern
Finalmente, é justo falarmos de um Anti-Pattern em específico: O Spaghetti Code (As Long As It Can Be).
Como o próprio nome sugere, o código é muito parecido com um spaghetti (comprido, complexo e com muitos nós). Sua implementação comumente se torna errática, ineficiente e muito sujeita a erros.
Infelizmente, o Spaghetti Code é mais comum do que gostaríamos e representa o "lado negro da força", afinal, hoje existem diversas linguagens de desenvolvimento que tem como pilar a orientação a objetos, e uma programação "spaghetti" torna-se um pecado mortal neste meio. Devemos lembrar ainda que o Spaghetti Code prega exatamente o contrário que os princípios da programação orientada a objetos (herança, polimorfismo e encapsulamento).
Contribuição
Alexandre Saláfia (asalafia@gmail.com) - Expressão: As Long As It Can Be
Igor Leite (igoravl@gmail.com) - Termo: IvosFaz