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 Moralez



A expressão do título pode soar um pouco lúdica para algumas pessoas, mas ela reflete a dura realidade da maioria dos projetos de softwares que foram ou estão sendo desenvolvidos, ou seja, o IvosFaz (Irmos fazendo. Literalmente sem controle).

Nã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.

  • 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.

  • 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.
Vantagens e Desvantagens

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

Guilherme Bacellar Moralez

Guilherme Bacellar Moralez - Bacharel em Ciências da Computação, Desenvolvedor .NET há 4 anos, MCAD, Autor de Livros e Artigos, Arquiteto de Software do Projeto D.NET (Framework de Desenvolvimento .NET).
Blog:
http://dotnetmax.bacellar.org/