Pessoal implementei um pouco diferente. O que vcs acham?
package br.com.schimidtsolutions.estudo.descontos;
import com.google.common.collect.Lists;
public class CalculadoraDescontoTest {
public static void main(final String[] args) {
Desconto descontoMaisQueCincoItens = new DescontoParaMaisDeCincoItens();
descontoMaisQueCincoItens.tendoComoProximoDescontoNaAvaliacao(new DescontoParaMaisDeQuinhentosReais())
.tendoComoProximoDescontoNaAvaliacao(new SemDesconto()); // Agora totalmente opcional o Sem Desconto
Item mesa = new Item("MESA", 250);
Item mesa1 = new Item("MESA", 250);
Item mesa2 = new Item("MESA", 250);
Item mesa3 = new Item("MESA", 250);
Item mesa4 = new Item("MESA", 250);
Item cadeira = new Item("CADEIRA", 250);
Orcamento orcamento = new Orcamento(Lists.newArrayList(mesa, mesa1, mesa2, mesa3, mesa4, cadeira));
double calcularDesconto = descontoMaisQueCincoItens.calcularDesconto(orcamento);
System.out.println(calcularDesconto);
}
}
package br.com.schimidtsolutions.estudo.descontos;
import java.util.Objects;
public abstract class Desconto {
private static final Desconto SEM_DESCONTO = new SemDesconto();
private Desconto proximoDesconto = SEM_DESCONTO;
abstract double calcularDesconto(Orcamento orcamento);
final Desconto tendoComoProximoDescontoNaAvaliacao(final Desconto proximoDesconto) {
Objects.requireNonNull(proximoDesconto);
this.proximoDesconto = proximoDesconto;
return proximoDesconto;
}
Desconto getProximoDesconto() {
return proximoDesconto;
}
}
package br.com.schimidtsolutions.estudo.descontos;
public class DescontoParaMaisDeQuinhentosReais extends Desconto {
@Override
public double calcularDesconto(final Orcamento orcamento) {
if (orcamento.getValorTotal() > 500) {
System.out.printf("Desconto para mais de quinhentos reais aplicado no valor de R$ %.2f!\n", orcamento.getValorTotal());
return orcamento.getValorTotal() * 0.07;
}
return getProximoDesconto().calcularDesconto(orcamento);
}
}
package br.com.schimidtsolutions.estudo.descontos;
public class DescontoParaMaisDeCincoItens extends Desconto {
@Override
public double calcularDesconto(final Orcamento orcamento) {
if (orcamento.getQuantidadeItens() > 5) {
System.out.printf("Desconto para mais de cinco itens aplicado no orçamento de %d itens!\n", orcamento.getQuantidadeItens());
return orcamento.getValorTotal() * 0.1;
}
return getProximoDesconto().calcularDesconto(orcamento);
}
}
package br.com.schimidtsolutions.estudo.descontos;
public class Item {
private final String nome;
private final double valor;
public Item(final String nome, final double valor) {
this.nome = nome;
this.valor = valor;
}
public String getNome() {
return nome;
}
public double getValor() {
return valor;
}
}
package br.com.schimidtsolutions.estudo.descontos;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class Orcamento {
private final List<Item> itens;
private double valor;
public Orcamento(final List<Item> itens) {
Objects.requireNonNull(itens);
this.itens = itens;
recalcularValorTotal();
}
public List<Item> getItens() {
return Collections.unmodifiableList(itens);
}
public void adicionarItem(final Item item) {
itens.add(item);
recalcularValorTotal();
}
public int getQuantidadeItens() {
return itens.size();
}
public double getValorTotal() {
return valor;
}
private void recalcularValorTotal() {
valor = itens.stream().mapToDouble(Item::getValor).sum();
}
}
package br.com.schimidtsolutions.estudo.descontos;
public class SemDesconto extends Desconto {
@Override
public double calcularDesconto(final Orcamento orcamento) {
return 0;
}
}