Aplicando a Lei de Demeter em nossos códigos
Quando estamos na universidade aprendemos sobre classes, objetos, atributos, métodos, herança, polimorfismo, etc. A ideia principal por trás da orientação a objetos é olhar para o problema que queremos resolver, abstrair as informações necessárias e montar um "quebra-cabeça" que vai solucionar nosso problema.
Esse quebra-cabeça é composto por nossos objetos que devem trocar mensagens entre si para chegar a uma solução. Quando estamos escrevendo nossos códigos, devemos sempre nos perguntar. "O próximo desenvolvedor que olhar para esse código vai entende-lo com facilidade?", "Há alguma classe que faz coisas demais?", etc. Como o processo de codificar é algo muito abstrato e varia de desenvolvedor para desenvolvedor, devemos seguir algumas regras para programar da melhor forma possível.
Existem diversos guias para nos auxiliar nessa jornada, Clean Code, princípios SOLID, entre outros. Porém, nesse post, falarei sobre a Lei de Demeter. Veremos como essa lei funciona com um exemplo prático.
Nesse exemplo, somamos todos os itens de um carrinho de compras, para isso existe a classe Product que representa um produto contendo seu nome e valor. Há também a classe Item responsável por compor os itens do carrinho de compras, ela guarda o produto e a quantidade. Por fim, temos a classe Cart que representa o carrinho de compras, responsável por somar o valor de todos os itens.
Embora o código acima parece simples e inofensivo ele apresenta um problema de encapsulamento. Olhando para o método totalValueOfItems, vamos notar que na linha 14 é chamado o produto do item para então chamar seu valor.
Isso é um problema, porque caso a classe Item mude, o código desse método irá quebrar, e se o projeto não tiver testes para detectar isso? E se códigos assim estiverem espalhados por toda nossa aplicação? É certo o próximo desenvolvedor tem que usar ctrl + F para saber onde deve mudar?
Evitar esses problemas é simples, apenas devemos deixar os donos da informação manipulá-la, para isso vamos refatorar as classes.
O que mudou com essa pequena alteração ? Agora, está melhor encapsulado porque a classe que conhece o produto e a quantidade está fazendo essa soma e a classe Cart que conhece todos os itens está acumulando o valor para retornar o total no carrinho.
Quando vamos utilizar métodos de outras classes devemos saber sempre o que o método faz e nunca como ele faz. Seguindo isso, evitamos o bad smell chamado Feature Envy.
Explicando melhor a Lei de Demeter
Foi proposta por Ian Holland em 1987, leva esse nome porque foi descoberta durante o desenvolvimento do The Demeter Project na Northeastern University.
A ideia dela é "Converse apenas com seus amigos", levando isso em consideração temos na classe Item o método totalValue que trabalha com o valor do produto apenas porque ele conhece a classe do produto por isso pode pedir seu valor.
Para saber mais sobre a Lei de Demeter, recomendo a leitura do The Paperboy, The Wallet, and The Law Of Demeter e também o livro Pragmatic Programmer.