Pessoal a verificação do item não fica mais OO se a mesma ficar dentro do orcamento? Outra dúvida minha é se posso fazer fluent interface na construção do encadeamento das classes.
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;
public 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 CalculadoraDescontos {
public double calcularDesconto(final Orcamento orcamento) {
Desconto descontoMaisQueCincoItens = new DescontoParaMaisDeCincoItens();
descontoMaisQueCincoItens.tendoComoProximoDescontoNaAvaliacao(new DescontoParaMaisDeQuinhentosReais())
.tendoComoProximoDescontoNaAvaliacao(new DescontoPorVendaCasada());
return descontoMaisQueCincoItens.calcularDesconto(orcamento);
}
}
package br.com.schimidtsolutions.estudo.descontos;
public class DescontoPorVendaCasada extends Desconto {
@Override
public double calcularDesconto(final Orcamento orcamento) {
if (isVendaCasadaOcorreu(orcamento)) {
System.out.println("Desconto para venda casada no orçamento!");
return orcamento.getValorTotal() * 0.05;
}
return 0;
}
private boolean isVendaCasadaOcorreu(final Orcamento orcamento) {
return orcamento.isItemNaLista("LAPIS") && orcamento.isItemNaLista("CANETA");
}
}
package br.com.schimidtsolutions.estudo.descontos;
import com.google.common.collect.Lists;
public class CalculadoraDescontoTest {
public static void main(final String[] args) {
CalculadoraDescontos calculadoraDescontos = new CalculadoraDescontos();
Item mesa = new Item("LAPIS", 250);
Item mesa1 = new Item("CANETA", 250);
Orcamento orcamento = new Orcamento(Lists.newArrayList(mesa, mesa1));
System.out.println(calculadoraDescontos.calcularDesconto(orcamento));
}
}
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 boolean isItemNaLista(final String nomeItem) {
return itens.indexOf(new Item(nomeItem)) > -1;
}
public int getQuantidadeItens() {
return itens.size();
}
public double getValorTotal() {
return valor;
}
private void recalcularValorTotal() {
valor = itens.stream().mapToDouble(Item::getValor).sum();
}
}