Aplicar o Princípio Aberto/Fechado (OCP) para eliminar a necessidade de modificar a classe DiscountCalculator
sempre que surgir um novo tipo de cliente.
Queremos que a calculadora fique aberta para extensão (novas políticas de desconto) e fechada para modificação (não precisa mais de switch
/if
).
Hoje a DiscountCalculator
contém um switch
em CustomerType
:
public double apply(double amount, CustomerType type){
switch (type){
case REGULAR: return amount * 0.95;
case PREMIUM: return amount * 0.90;
default: return amount;
}
}
Isso viola o OCP porque, ao adicionar um novo tipo de cliente (PARTNER
, por exemplo), somos obrigados a editar essa classe.
No código legado, o tipo PARTNER
não é tratado → os testes existentes falham.
Sua tarefa é refatorar para respeitar OCP.
- Pacote:
br.com.mariojp.solid.ocp
- Classes iniciais:
CustomerType.java
→ Enum comREGULAR, PREMIUM, PARTNER
DiscountCalculator.java
→ Implementação comswitch
- Testes em:
src/test/java/br/com/mariojp/solid/ocp/DiscountCalculatorTest.java
- Verificam que
PARTNER
deve ter 12% de desconto (100 → 88). - Também verificam que a calculadora aceita injeção de políticas de desconto, sem depender de
switch
.
- Verificam que
mvn -q test
- Clone o repositório da atividade.
- Abra no IDE (IntelliJ / VS Code / Eclipse).
- Leia o código legado em
src/main/java/br/com/mariojp/solid/ocp/
. - Rode os testes (
mvn -q test
) → eles falham inicialmente. - Refatore aplicando OCP:
- Crie uma interface
DiscountPolicy
que defineapply(double amount)
. - Implemente políticas concretas:
RegularPolicy
,PremiumPolicy
,PartnerPolicy
. - Ajuste
DiscountCalculator
para receber um mapa de políticas (injeção).
- Crie uma interface
- Garanta que novos tipos possam ser adicionados sem modificar
DiscountCalculator
. - Rode novamente os testes até ficarem verdes .
- Faça commits pequenos e dê push no repositório.
- Projeto compila (2 pts)
- Refatoração remove
switch
e usa abstrações adequadas (3 pts) - Solução segue OCP: fácil adicionar novos descontos sem editar
DiscountCalculator
(3 pts) - Todos os testes passam (2 pts)