Você acha que existe alguma coisa errada com a linha de código abaixo:
Vou colocar no contexto, digamos que este trecho de código faça parte de um método que faz uma série de processamentos nas ordem de vendas a serem entregues dependendo do estado de entrega. Por isto, preciso buscar o estado do endereço do cliente associado a ordem.
O problema é que este tipo de chamada encadeada (order.Customer.Address.StateId) esconde um acoplamento indesejado. O acoplamento entre as classes não se mede apenas pelas referências diretas na classe, mas também pelo quanto uma classe conhece da outra.
Este pequeno trecho de código não apenas conhece a classe Order, mas também conhece a classe Customer e a regra implícita que o endereço de entrega de uma ordem é o endereço do cliente.
Se um novo requisito deste aplicativo fosse que o cliente poderia solicitar a entrega do pedido para um outro endereço (a maioria das lojas na web permite isto) este código estaria automaticamente defasado. Assim como todos que acessaram o endereço do cliente diretamente.
Uma das formas de evitar este tipo de acoplamento é seguir a Law of Demeter, que diz que o método de um objeto deve chamar somente métodos e propriedades que possa acessar diretamente.
A idéia é saber o minímo possível sobre a estrutura interna de outros objetos, portanto não há problemas de executar métodos do objeto que eu instanciei, mas acessar métodos de objetos me que são retornados me faz conhecer um pouco mais do que gostaria.
Uma forma simples de aplicar a Law of Demeter é nunca utilizar dois pontos em uma mesma chamada. No exemplo acima ao invés de acessar diretamente o endereço do cliente eu deveria ter criado um método ou propriedade que retornasse o endereço de entrega da ordem, abstraindo o acesso ao endereço do cliente.
Desta forma meu método ficaria assim:
Ainda assim tenho dois pontos na chamada, para evitar isto teria que criar uma propriedade, DeliveryState
Então o código final ficaria:
Este estilo de código, no entanto, pode trazer complexidade, é necessário aplicá-lo com bom senso. No exemplo acima é possível chegar a conclusão de que é aceitável que este método conheça alguns detalhes da classe Address, afinal o risco do endereço deixar de ter estado, ou mudar esta propriedade não seria tão grande. O Jay Fields também fala sobre este problema em um post recente.
Mas vale a pena levantar um ponto de interrogação sempre uma chamada começar a “acumular pontos”
Referências:
OBS.: A tradução de Demeter para Demétrio é apenas uma brincadeira minha, pelo que pesquisei Demeter é uma deusa grega e não me perguntem porque o seu nome foi usado nesta lei.