Um padrão Decorator permite mudar a superfície de um objeto e um padrão Strategy permite mudar o seu interior. Portanto, essas são duas maneiras diferentes de mudar um objeto.
Uma vez que o padrão Decorator somente muda o componente do ponto de vista exterior, o componente não precisa saber coisa alguma sobre seus decoradores; ou seja, os decoradores são transparentes para o componente.
Quando se usam estratégias, o próprio componente conhece as extensões possíveis. Assim, cabe ao componente referenciar e manter as suas estratégias correspondentes.
A abordagem baseada no Strategy pode exigir a modificação do componente para acomodar novas extensões.
Por outro lado, uma estratégia pode ter uma interface especializada, enquanto que a interface de um decorador deve estar em conformidade com a do componente.
Funcionalidade estendida por Decorator x Strategy
Quando Component (Decorator) e Context (Strategy) forem a mesma entidade, é importante lembrar:
Por default, as classes decorativas não precisam de alterações.
Por default, as classes de estratégia não precisam de alterações.
A classe Component/Context deve:
adicionar o método abstrato de decoração;
criar referência a estratégia;
escrever o método construtor com atribuição de valor para a referência de estratégia;
adicionar o método set de estratégia;
adicionar o método da estratégia.
A classe cliente principal deve:
criar referências ao tipo Component/Context, contendo objetos Component/Context concretos.
Se você decidir combinar esses padrões em uma única classe, a classe Component/Context terá que lidar tanto com a variabilidade de algoritmos (Strategy) quanto com a extensão dinâmica de responsabilidades (Decorator). Aqui estão algumas considerações:
A combinação dos padrões pode aumentar a complexidade da classe Component/Context. Isso pode tornar a manutenção e a compreensão do código mais desafiadoras.
A flexibilidade do sistema pode ser mantida, mas é crucial entender que essa abordagem pode resultar em uma classe que tem muitas responsabilidades. Se a flexibilidade for uma prioridade, a combinação pode ser justificada.
ATENÇÃO MÁXIMA: Após a aplicação de uma decoração não é possível mudar a estratégia, uma vez que a referência ao objeto original é "perdida".
O sistema desenvolvido é um modelo de atendimento médico que combina os padrões de projeto Strategy e Decorator para permitir flexibilidade na cobrança dos serviços e na adição de características extras ao atendimento.
O sistema permite que diferentes formas de cobrança sejam aplicadas ao atendimento médico, como:
Cobrança Particular (sem desconto)
Cobrança por Convênio (20% de desconto)
Cobrança pelo SUS (gratuito)
O atendimento pode mudar dinamicamente sua estratégia de cobrança de acordo com o tipo de atendimento que foi necessário, garantindo flexibilidade no sistema.
Além da cobrança, o sistema permite adicionar funcionalidades extras ao atendimento por meio do padrão Decorator. Por exemplo:
Atendimento com Especialista (adiciona um custo extra de 40%)
Atendimento com Cirurgião (adiciona um custo extra de 100%)
O Decorator possibilita que novos tipos de atendimento sejam combinados ao longo do atendimento sem modificar diretamente a classe base.
O tipo BigDecimal foi escolhido porque ele oferece alta precisão para operações matemáticas envolvendo valores monetários. Diferente de float e double, que podem introduzir erros de arredondamento devido à representação binária dos números decimais, BigDecimal evita esse problema e permite um controle preciso sobre a escala e arredondamento, o que é essencial para cálculos financeiros em um sistema de saúde.
Além disso, o BigDecimal suporta operações matemáticas com precisão configurável, garantindo que os cálculos de cobrança e descontos sejam exatos, sem perda de precisão.