Decorator Pattern


Como agregar responsabilidade a Objetos individuais, em tempo de execução, independente de sua Classe?

Utilizando Decorator Pattern.

Os Decoradores oferecem uma alternativa simples e flexível ou uso de subclasses para extensão de funcionalidades.

Decorator

Para mim, Decorador é um dos mais importantes padrões de design. Infelizmente esse padrão quase nunca é utilizado, pelo menos nos projetos que vi nos últimos anos, independentemente da linguagem de programação utilizada.

Por que?

Não tenho uma resposta exata, mas suponho que o motivo do não uso de Decoradores seja devido a escolha “natural” de utilizarmos Herança de Classes para estender funcionalidades.

Aprendemos que a Orientação a Objetos tem 3 pilares: Herança, Encapsulamento e Polimorfismo.

Herança de Classe é utilizada para estender funcionalidades, implementando uma nova Classe que herda as funcionalidades da primeira e de toda uma hierarquia. Então você acha que usar Herança sempre será a escolha mais correta para extensão de funcionalidades?

Eu acho que não. Em 90~95% dos casos, eu utilizo Decoradores e Composição de Objetos.

Um Decorador oferece uma abordagem do tipo "use quando for necessário” para adição de responsabilidades. Em vez de tentar suportar todas as características previsíveis em uma Classe complexa e customizada, você pode definir uma Classe simples e acrescentar funcionalidade de modo incremental com objetos Decoradores.

— Padrões de Projeto, Erich Gamma, pág.173

Decoradores são tão simples de implementar como Herança, mas traz mais benefícios.

  • Você não precisa prever o futuro utilizando Decoradores. Utilizando Herança você tem que se preocupar com a hierarquia das Classes desde o início, desde a Classe mais básica até a mais específica, como se pudesse prever o futuro;
  • Evita Classes sobrecarregadas de características e funcionalidades;
  • Classes pequenas e coesas;

Exemplos de código?

  1. Parte do código de um projeto em produção que utiliza Decoradores para consumir um WebService, aqui.
  2. Implementação de um Log com Decoradores para memória, arquivo, banco de dados e e-mail, aqui;
  3. Utilizando a Classe TEmployeeSalaryWithCommission como Decorador de TEmployeeSalary, aqui;

Até logo.

Posts Relacionados

  • Mais Performance usando Argumentos "const" para Interfaces

  • Herança de Formulário é para Iniciantes

  • Eliminando Métodos Privados

  • Classes Aninhadas

  • API Unit: Tudo num só lugar

  • Injeção de Dependência sem XML, Atributos/Anotações ou Frameworks

  • Nomeando Classes em Libraries

  • Versionando e Organizando seus Pacotes

  • Xavier Package

  • Inter-process Communication