Countdown

Final Countdown

Faltam dias. Ou segundos.

segunda-feira, 15 de junho de 2015

#26) Design Patterns


Olá!

Hoje trataremos do assunto Design Patterns, que são princípios de desenvolvimento de software fáceis de serem compreendidos, modificados e expandidos. É uma solução para um problema que ocorre com frequência durante o projeto de Software, servindo como um modelo para a implementação de um programa.

Queremos evitar a implementação de uma classe God centralizada que realiza todas as tarefas do nosso programa: https://en.wikipedia.org/wiki/God_object
Implementação que vai contra os princípios de Design Patterns.

O que diferencia um programador amador de um profissional? Um amador gera códigos compiláveis sem se preocupar com a estrutura de seu código, enquanto um profissional emprega os princípios de Design Patterns para desenvolver um código muito eficiente do ponto de vista de projeto, apto a sofrer atualizações e modificações ao longo do tempo.

O site PrinciWeb traz uma abordagem bem lúdica sobre o tema:

Design patterns (padrões de projeto) surgiram com a motivação de ajudar a solucionar problemas que ocorrem frequentemente, e, se usados com bom senso, podem se tornar ferramentas poderosas para qualquer desenvolvedor de software, uma vez que já foram testadas, utilizadas e aprimoradas a partir da experiência e conhecimento de outros programadores.
Preparamos um post explicando o que são design patterns e seus princípios comuns, baseado no livro “Professional ASP.NET Design Patterns” de Scott Millett.
Design Patterns - Vida de Programador
Tirinha retirada do site Vida de Programador, o qual publica tirinhas diárias com histórias engraçadas e verídicas sobre o dia-a-dia de um programador.

Explicando Design Patterns

Design patterns (Padrões de projeto) são soluções de templates abstratas de alto nível. Pense nelas como um “blueprint” (desenho técnico ou documentação de uma arquitetura, etc.) para soluções e não como uma solução por si própria. Você não achará um framework que você poderá simplesmente aplicar para a sua aplicação; ao invés disso, você chegará ao design patterns através da refatoração do seu código e generalização do seu problema.
Design patterns não são somente aplicados em desenvolvimento de software; design patterns podem ser encontrados em diversas áreas da vida, da engenharia até da arquitetura. Em fato, foi o arquiteto Christopher Alexander que introduziu a ideia de patterns em 1970 para construir um vocabulário comum para discussões sobre design. Ele escreveu:
Cada pattern descreve um problema que ocorre várias vezes ao nosso redor e com isso, descrevem a solução para o problema de uma maneira que você pode usar essa solução diversas vezes sem ter que fazer a mesma coisa duas ou mais vezes.

Vamos então abordar os principais conceitos de Design Patterns:

Princípios de Design

Alguns dos princípios mais conhecidos de Desing Patterns voltados para o desenvolvimento de software nível empresarial são citados abaixo:
  1. DRY (Don't Repeat Yourself) : Não repetir o código, utilizar abstrações para coisas comuns.
  2. KISS (Keep It Simple Stupid) : Tentar manter o código o mais simples possível.
  3. TDA (Tell, Don't Ask) : Você deve dizer ao objeto qual tarefa ele deve realizar, sem se preocupar com o estado dele. Ou seja, promove o encapsulamento do código e torna as classes mais independentes.
  4. YAGNI (You Ain't Gonna Need It) : Adicionar somente as funcionalidades necessárias para o funcionamento da aplicação.
  5. TDD (Test Driven Development) : Método de desenvolvimento baseado em testes: O desenvolvimento da aplicação é inteiramente voltada para o êxito dos testes criados.
  6. SoC (Separation of Concerns) : Separa o código em funcionalidades distintas, promovendo o seu encapsulamento e distribuindo responsabilidades para cada classe.
Podemos ainda citar alguns princípios por trás dos princípios:
  1. Encapsular : Encapsular todo o código passível de alteração no futuro.
  2. Programar para a Interface, não para a implementação.
  3. Não implementar responsabilidades que devem ser delegadas às classes.
  4. Preferir a composição invés da herança, devido à sua maior flexibilidade.

Princípios de Design Orientado a Objetos

Vamos agora abordar SOLID, 5 princípios básicos de design orientado a objetos. Indico fortemente a referência http://www.itexto.net/devkico/?p=1105 para obter exemplos práticos da aplicação destes princípios.

  • Single Responsibility (SRO): Cada classe deve ter uma única responsabilidade. Isso distribui as tarefas evitando a sobrecarga em uma única classe, reduzindo o código fonte e eliminando problemas de bugs.
  • Open Closed Design (OCP): As classes devem ser abertas para extensões e fechadas para modificações.
  • Liskov Substitution : As subclasses devem sempre aumentar as funcionalidades das superclasses, nunca reduzi-las.
  • Interface Segregation (ISP) : Evitar a criação de classes poderosas. Se uma classe tem muitas funcionalidades, empregar interfaces para diferentes responsabilidades, dividindo as tarefas.
  • Dependency Injection (DIP) : Um módulo de nível superior não deve depender de um módulo de nível inferior. Ambos devem depender apenas de abstrações.

Padrões GoF (Group of Four)

Da referência http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software, temos uma pequena lista de padrões GoF, bem como a sua classificação:
Os padrões "GoF" são organizados em 3 famílias :
  • Padrões de criação : relacionados à criação de objetos
  • Padrões estruturais : tratam das associações entre classes e objetos.
  • Padrões comportamentais : tratam das interações e divisões de responsabilidades entre as classes ou objetos.

Padrões de criação

  • Abstract Factory : Através dele uma classe simplesmente cria o objeto que você gostaria de usar.
  • Builder : Encapsular a construção de um produto, construindo-o por etapas.
  • Factory Method : As subclasses decidem quais classes concretas serão criadas.
  • Prototype : Permite criar novas instâncias clonando instâncias já existentes.
  • Singleton : Uma classe que só possui uma única instância. Já mostrei esse conceito no blog, no post "objeto global".

Padrões estruturais

  • Adapter : Envelopa o objeto e fornece a ele uma interface diferente.
  • Bridge : Cria uma ponte para variar implementações e abstrações.
  • Composite : O cliente trata as coleções de objetos e objetos individuais de maneira uniforme.
  • Decorator : Envelopa objeto para fornecer novos comportamentos.
  • Façade (ou Facade) : Simplifica a interface de um conjunto de classes.
  • Flyweight : Uma instância de uma classe pode fornecer várias instâncias virtuais (como o casa da bala virtual, no jogo Bizuca).
  • Proxy : Envelopa o objeto para controlar o acesso a ele.

Padrões comportamentais

  • Chain of Responsibility : Permite a mais de um objeto a oportunidade de processar uma solicitação.
  • Command : Encapsula uma solicitação como um objeto.
  • Interpreter : Constrói um intérprete para uma linguagem (como o uso de protocolos de comunicação em uma aplicação Cliente - Servidor, que precisa codificar todas as informações do projeto em uma String, por exemplo).
  • Iterator : Permite acessar sequencialmente uma coleção de objetos sem expor a sua implementação (Como, por exemplo, quando percorremos um ArrayList).
  • Mediator : Centraliza operações complexas de comunicação e controle de entre objetos relacionados (classe Comunicação entre cliente e servidor, por exemplo).
  • Memento : Permite restaurar o objeto a um de seus estados prévios (desfazer). Um exemplo já mostrado no blog é a funcionalidade Canvas do HTML, que permite salvar seu estado (ctx.save()) e restaurá-lo posteriormente (ctx.restore()), desfazendo translações, rotações, etc.
  • Observer : Permite notificar outros objetos sobre mudanças de estado.
  • State : Encapsula comportamentos em baseados em Estados e usa delegações para alternar comportamentos. (Também usado no projeto Web Bizuca, estados para recibo de mensagens).
  • Strategy : Encapsula famílias de algoritmos permitindo à classe cliente instanciar estes algoritmos  sem necessitar reconhecer a sua implementação atual.
  • Template Method : As subclasses decidem como implementar os passos de um algoritmo.
  • Visitor : Permite acrescentar novos recursos a um composto de objetos.
Um padrão "GoF" também é classificado segundo o seu escopo em 2 outros grupos :

Bem, com isso concluímos o post de hoje, que dá um panorama generalizado do que são Design Patterns. Caso o leitor se interessar pelo conteúdo, pode aprofundar o seu estudo com exemplos práticos nas referências abaixo:

Referências:

(Exemplos práticos dos princípios SOLID):

(Fala dos princípios básicos de Design Patterns):
http://www.princiweb.com.br/blog/programacao/design-patterns/o-que-sao-design-patterns.html

(Padrões GoF):
http://pt.wikipedia.org/wiki/Padr%C3%A3o_de_projeto_de_software
http://www.devmedia.com.br/design-patterns-descricoes-dos-padroes-gof-parte-2/16781

(Exemplos de GoF (em PHP)):
http://br.phptherightway.com/pages/Design-Patterns.html

(Considere essa referência como uma enciclopédia para consulta):
https://lealcy.wordpress.com/gambi-design-patterns/

Nenhum comentário:

Postar um comentário