Costumo encontrar esse problema, especialmente em Java, mesmo que eu ache que seja um problema geral de POO. Ou seja: criar uma exceção revela um problema de design.
Suponha que eu tenha uma classe que tenha um String namecampo e um String surnamecampo.
Em seguida, ele usa esses campos para compor o nome completo de uma pessoa, a fim de exibi-lo em algum tipo de documento, digamos uma fatura.
public void String name;
public void String surname;
public String getCompleteName() {return name + " " + surname;}
public void displayCompleteNameOnInvoice() {
String completeName = getCompleteName();
//do something with it....
}
Agora, quero reforçar o comportamento da minha classe lançando um erro se displayCompleteNameOnInvoicefor chamado antes que o nome seja atribuído. Parece uma boa ideia, não é?
Eu posso adicionar um código de exceção ao getCompleteNamemétodo. Mas dessa maneira estou violando um contrato "implícito" com o usuário da classe; em geral, os getters não devem lançar exceções se seus valores não estiverem definidos. Ok, este não é um getter padrão, pois não retorna um único campo, mas, do ponto de vista do usuário, a distinção pode ser sutil demais para pensar sobre isso.
Ou posso lançar a exceção de dentro do displayCompleteNameOnInvoice. Mas, para fazer isso, eu deveria testar diretamente os campos nameou surname, violando a abstração representada por getCompleteName. É responsabilidade deste método verificar e criar o nome completo. Pode até decidir, baseando a decisão em outros dados, que, em alguns casos, é suficiente surname.
Portanto, a única possibilidade parece alterar a semântica do método getCompleteNamepara composeCompleteName, o que sugere um comportamento mais "ativo" e, com ele, a capacidade de gerar uma exceção.
Essa é a melhor solução de design? Estou sempre procurando o melhor equilíbrio entre simplicidade e correção. Existe uma referência de design para esse problema?
displayCompleteNameOnInvoicebasta lançar uma exceção se getCompleteNameretornar null, não é?