Padrão Decorator
O Padrão Decorator é um padrão de projeto estrutural que permite adicionar responsabilidades a um objeto de maneira dinâmica, criando algo similar a uma extensão do objeto. Geralmente isso é feito através de camadas aninhadas.
Geralmente este padrão é composto por alguns elementos:
Definição abstrata de um componente de software;
Implementação concreta deste componente;
Definição abstrata de um decorator para este componente;
Uma ou mais implementações concretas do decorator do componente;
Problema
Imagine um componente do sistema que calcula um salário de um funcionário. Esse cálculo envolve vários condições, como:
Horas trabalhadas
Horas extras (que tem acréscimo de 20% do valor na hora trabalhada)
Se existem descontos na folha por plano de saúde/odontológico.
Em um primeiro momento, podemos pensar em várias condicionais para o nosso código, verificando cada um desses aspectos e calculando o valor de acordo. Porém, essas condicionais tendem a crescer e deixar o código cada vez mais complicado de ser entendido. Além disso, alterar essa classe para acrescentar uma nova regra, quebra o princípio de aberto/fechado, como já vimos anteriormente.
Então, como podemos acrescentar novas condicionais dinamicamente e a medida que for necessário?
Solução
A solução proposta pelo Decorator passa pela separação de cada uma das responsabilidades "opcionais" em classes que vão envolver uma calculadora de salário, adicionando essas responsabilidades por demanda. Começaremos criando uma classe base de Calculadora de salário, em forma de interface. Vamos ao exemplo em código:
De um lado, teremos uma calculadora de salário base, que sempre será utilizado, independente das condicionais.
De outro lado, temos as classes que podem envolver/decorar essa CalculadoraSalarioFuncionario
, adicionando novas funcionalidades. Como queremos permitir que sejam criadas novos decoradores a medida que for necessário, criaremos uma classe abstrata que tem um objeto do tipo CalculadoraSalario
. Isso será a base de nosso Decorator.
As classes que implementam esse Decorator definem os fragmentos de algoritmos que serão acrescentados a calculadora base. Nesse caso, verificamos se as horas informadas passam das 160 horas normais (em um mês) e calculamos o excedente com o valor da hora extra.