public abstract class Imposto {
protected Imposto outroImposto;
public Imposto(Imposto outroImposto) {
this.outroImposto = outroImposto;
}
public Imposto() {
}
public abstract double calcular(Orcamento orcamento);
protected double calculoDoOutroImposto(Orcamento orcamento) {
if (outroImposto == null) return 0;
return outroImposto.calcular(orcamento);
}
}
public class ICMS extends Imposto {
public ICMS(Imposto imposto) {
super(imposto);
}
public ICMS() {
}
@Override
public double calcular(Orcamento orcamento) {
return orcamento.getValor() * 0.1 + calculoDoOutroImposto(orcamento);
}
}
public class ICPP extends TemplateDeImpostoCondicional{
@Override
public double minimaTaxacao(Orcamento orcamento) {
return orcamento.getValor() * 0.07;
}
@Override
public double maximaTaxacao(Orcamento orcamento) {
return orcamento.getValor() * 0.05;
}
@Override
public boolean deveUsarMaximaTaxacao(Orcamento orcamento) {
return orcamento.getValor() > 500;
}
}
public class IKCV extends TemplateDeImpostoCondicional {
private boolean temItemMaiorQue100ReaisNo(Orcamento orcamento) {
// Ordenando os valores descrecente para melhorar a performance
// orcamento.getItens().sort((s1, s2) -> Double.compare(s2.getValor(), s1.getValor()));
for (Item item : orcamento.getItens()) {
System.out.println(item.getValor());
if (item.getValor() > 100)
return true;
}
return false;
}
@Override
public double minimaTaxacao(Orcamento orcamento) {
return orcamento.getValor() * 0.06;
}
@Override
public double maximaTaxacao(Orcamento orcamento) {
return orcamento.getValor() * 0.10;
}
@Override
public boolean deveUsarMaximaTaxacao(Orcamento orcamento) {
return orcamento.getValor() > 500 && temItemMaiorQue100ReaisNo(orcamento);
}
}
public class ISS extends Imposto {
public ISS(Imposto outroImposto) {
super(outroImposto);
}
public ISS() {
}
@Override
public double calcular(Orcamento orcamento) {
return orcamento.getValor() * 0.06 + + calculoDoOutroImposto(orcamento);
}
}
public class TesteDeImpostosComplexos {
public static void main(String[] args) {
Imposto iss = new ISS(new ICMS(new ICPP()));
Orcamento orcamento = new Orcamento(500);
double valorImposto = iss.calcular(orcamento);
System.out.println(valorImposto);
}
}