Feature Envy

Inveja é bom? Claro que não! Inveja é um dos sete pecados capitais! Agora, imagine se houver inveja entre as classes de um programa? Ops, isso significa que, neste caso, o desenvolvedor está cometendo um pecado capital no seu código? Faz sentido.
Acompanhe o artigo e entenda melhor o que é uma Feature Envy!

Introdução

Bom, já sabemos que o Clean Code nos ensinar a praticar a expressividade e legibilidade no nosso código, certo? Porém, além disso, é importante considerar que a prática do Clean Code também evita que o nosso código “cheire mal”. Este termo, “Code Smells”, é mencionado por Martin Fowler no seu livro Refactoring: Improving the Design of Existing Code. Segundo o autor, há porções de código que, só de olhar, o desenvolvedor já faz careta, como se estivesse sentindo um cheiro ruim. Você deve ter se identificado com uma situação dessas, não? 🙂

Feature Envy é um dos elementos que causam esse “cheiro” e ocorre quando uma classe começa a utilizar, em excesso, as propriedades internas de outra classe. Em outras palavras, a classe não se limita a utilizar as propriedades que possui e acaba por utilizar propriedades externas. Na definição de Uncle Bob, é como se uma classe “desejasse” ser outra.

Exemplo de Feature Envy

Para explicar melhor, um exemplo prático! No código abaixo, provavelmente você já vai identificar os pontos em que há inveja:

Embora seja um exemplo bem básico, você notou a quantidade de vezes que as propriedades do objeto Produto são acessadas? O método ProcessarProduto obtém a descrição, quantidade, preço e desconto do item, além de, ainda por cima, incrementar o número de vezes que aquele produto foi vendido. Agora você fez careta, não é? 🙂

O código acima é um exemplo típico de Feature Envy. O método ProcessarProduto inveja o escopo da classe TItemVenda, como se ele desejasse estar dentro dela. Além da má impressão que o código apresenta, a Feature Envy também pode elevar o acoplamento entre classes e causar dependências desnecessárias, portanto, é muito provável que outros problemas possam surgir a partir dessa “inveja”.

Para evitar o Feature Envy, aliás, para educar o código e ensiná-lo a não ter inveja (haha), basta trabalhar adequadamente com encapsulamento.

Na solução abaixo, observe como o código fica mais limpo e, claro, menos invejoso:

Na classe TItemVenda, essa seria a implementação dos métodos de acesso:

Mas, no método ProcessarProduto, você continua acessando a classe TItemVenda!
Sim, mas, ao invés de acessar diretamente as propriedades, estou acessando métodos encapsulados públicos, que são disponibilizados justamente para retornar valores internos. Na verdade, esse é um dos propósitos do encapsulamento da Orientação a Objetos. Não conhecemos as propriedades e nem os cálculos que ocorrem dentro do método ObterTotalItem, mas sabemos que ele irá nos retornar o total do item da venda.

Só mais uma observação: o incremento do número de vendas poderia ser mais confiável. Ao invés de um método, uma alternativa é criar uma Trigger no banco de dados para automatizar essa operação. Dessa forma, o número de vendas seria incrementado somente quando o item fosse efetivamente gravado no banco de dados, aumentando a confiabilidade e eliminando algumas linhas de código na aplicação.

 

Fico por aqui, pessoal.
Até a próxima semana!


André Celestino