Estou com uma dúvida de encapsulamento sobre o livre Orientação a Objetos e SOLID para Ninjas (pg 63 à 79).
Um exemplo de encapsulamento que ao meu ponto de vista é ótimo, por outro lado se revela inexequível. Gostaria de entender como o autor ou alguém que entenda do assunto resolveria esse problema de encapsulamento.
Objeto Inicial
Problema: o objeto ProcessadorDeBoletos consegue modificar propriedades da Fatura diretamente, deixando esse objeto não encapsulado
public class ProcessadorDeBoletos {
public void processa(List<Boleto> boletos, Fatura fatura){
double total = 0;
for(Boleto boleto : boletos){
Pagamento pagamento = new Pagamento(boleto.getValor(),MeioDePagamento.BOLETO);
fatura.getPagamentos().add(pagamento);
total += boleto.getValor();
}
if(total >= fatura.getValor()){
fatura.setPago(true);
}
}
}
Solução proposta pelo Livro
@Entity
public class Fatura{
@OneToOne
private Pagamento pagamento;
@OneToMany(fetch = FetchType.LAZY)
private List<Pagamento> pagamentos = new ArrayList<>();
public void adicionaPagamento(Pagamento pagamento){
this.pagamento.add(pagamento);
if(valorTotalDosPagamentos()>this.valor){
this.pago = true;
}
}
private Double valorTotalDosPagamentos(){
double total = 0;
for(Pagamento p : pagamentos){
total += p.getValor();
}
return total;
}
public class ProcessadorDeBoletos {
public void processa(List<Boleto> boletos, Fatura fatura){
for(Boleto boleto : boletos){
Pagamento pagamento = new Pagamento(boleto.getValor(),MeioDePagamento.BOLETO);
fatura.adicionaPagamento(pagamento);
}
}
}
Discussão
No meu ponto de vista essa solução não funciona por dois motivos:
- O relacionamento é de 1->muitos e portanto quando busco esse objeto Fatura no bando de dados ele não estará preenchido com os pagamentos.
- Eu não consigo acessar de dentro da @Entity Fatura o DAO para buscar essa lista de Pagamentos relacionados a essa fatura.
- Eu poderia executar o método fatura.adicionaPagamento(pagamento, pagamentos), porém eu quebraria o encapsulamento mais ainda pois estaria buscando todos os pagamentos para enviar a lista pronta para o método dentro da Entity
Não sei como resolver esse problema e já ví esse problema de encapsulamento várias vezes e a minha solução sempre foi não deixar o código encapsulado, pois não conheço a solução.
Obrigado a quem conseguir colaborar!