A atividade é um pouco vaga...
Usando "tudo que já foi ensinado no curso de Solid", podemos:
a) Simplesmente criar as interfaces, e instanciar a CalculadoraDePrecos com as implementações das duas interfaces (responsáveis pelos Calculos de Frete e Descontos);
public interface ITabelaDePreco {
double descontoPara(double valor);
}
public interface ITransportadora {
double para(String cidade);
}
public class CalculadoraDePrecos {
private final ITabelaDePreco tabela;
private final ITransportadora transportadora;
public CalculadoraDePrecos(ITabelaDePreco tabela, ITransportadora transportadora) {
this.tabela = tabela;
this.transportadora = transportadora;
}
public double calcula(Compra produto) {
final double valor = produto.getValor();
final double desconto = tabela.descontoPara(valor);
final double frete = transportadora.para(produto.getCidade());
return valor * (1 - desconto) + frete;
}
}
b) além das interfaces, aplicar alguns design patterns como Strategy, Chain of Responsability, Method Factory, etc.. para trazer coesão as implementações de TabelaDePrecoPadrao e Frete)...
Se o foco for em "tudo que já foi ensinado no curso de Solid", apenas as duas interfaces não garante baixo acoplamento e alta coesão...
o que resulta numa atividade muito mais extensa...