Navegando por algum código que escrevi, me deparei com a seguinte construção que me fez pensar. À primeira vista, parece bastante limpo. Sim, no código real, o getLocation()
método tem um nome um pouco mais específico que descreve melhor exatamente qual local ele obtém.
service.setLocation(this.configuration.getLocation().toString());
Nesse caso, service
é uma variável de instância de um tipo conhecido, declarada dentro do método this.configuration
é transmitido ao construtor da classe e é uma instância de uma classe implementando uma interface específica (que exige um getLocation()
método público ). Portanto, o tipo de retorno da expressão this.configuration.getLocation()
é conhecido; especificamente neste caso, é a java.net.URL
, enquanto service.setLocation()
quer a String
. Como os dois tipos String e URL não são diretamente compatíveis, é necessário algum tipo de conversão para ajustar a estaca quadrada no orifício redondo.
No entanto , de acordo com a Lei de Demeter como citado em Clean Code , um método f na classe C só deve chamar métodos em C , objetos criados por ou passados como argumentos para f , e objetos realizada em variáveis de instância de C . Qualquer coisa além disso (a final toString()
no meu caso particular acima, a menos que você considere um objeto temporário criado como resultado da própria invocação do método, caso em que toda a Lei parece discutível) é desaprovada.
Existe um raciocínio válido por que uma chamada como a acima, dadas as restrições listadas, deve ser desencorajada ou até proibida? Ou eu estou apenas sendo muito cuidadoso?
Se eu fosse implementar um método URLToString()
que simplesmente chama toString()
um URL
objeto (como o retornado por getLocation()
) passado a ele como parâmetro e retorna o resultado, eu poderia envolver a getLocation()
chamada nele para obter exatamente o mesmo resultado; efetivamente, eu apenas moveria a conversão um passo para fora. De alguma forma isso seria aceitável? ( Parece -me, intuitivamente, que isso não deve fazer nenhuma diferença, pois tudo o que faz é mudar um pouco as coisas. No entanto, seguindo a letra da Lei de Deméter, como citado, seria aceitável, pois eu estaria operando diretamente em um parâmetro para uma função.)
Faria alguma diferença se isso fosse algo um pouco mais exótico do que chamar toString()
um tipo padrão?
Ao responder, lembre-se de que alterar o comportamento ou API do tipo de que a service
variável é não é prático. Além disso, por uma questão de argumento, digamos que alterar o tipo de retorno getLocation()
também seja impraticável.