Czym byłoby ludzkie życie bez emocji, a zwłaszcza takiej jaką jest zazdrość? Można uważać, że bez niej żyłoby nam się po prostu lepiej. Ale to nie pora i miejsca na takie filozoficzne rozkminy. Dlaczego jednak wspominam o zazdrości? Ponieważ możemy ją napotkać w dowolnym kodzie aplikacji. Głownie doświadczyć jej mogą metody i to zjawisko nosi nazwę feature envy (jeden z code smells).

Feature envy dorobiło się nawet własnego mema
Feature envy dorobiło się nawet własnego mema

Jak rozpoznać feature envy?

Wyobraźmy sobie sytuację, w której mamy dwie klasy. Jedna z nich jest dobrze zaprojektowana i korzysta wyłącznie ze swoich elementów, czyli pól i metod. Natomiast druga posiada taką metodę, która zazdrości danych tej pierwszej klasie. Do wykonania żądanej logiki wykorzystuje praktycznie tylko pola i metody będące poza swoim obszarem. Może to wyglądać tak jak na poniższej grafice.

Metoda envyMethod posiada więcej zależności do Class B niż do swojej własnej
Metoda envyMethod posiada więcej zależności do Class B niż do swojej własnej

Czerwone strzałki reprezentują wykorzystanie elementów zewnętrznej klasy, natomiast zielone swoich własnych. Im grubsza linia tym większe użycie danego zasobu. Wychodzi na to, że metoda envyMethod znalazła się nie w tym miejscu, w którym powinna.

Leczenie dla feature envy

Jeśli wybrane dane zmieniają się w tym samym czasie to powinno się je trzymać w jednym miejscu, czyli np. w obrębie wybranej klasy. Gdy je zidentyfikujemy możemy użyć następujących mechanik, aby pozbyć się problemu feature envy.

  • W przypadku, gdy dana metoda powinna znaleźć się w innej klasie użyj techniki Move method (w IntelliJ po ustawieniu ‘karetki’ na nazwie metody wybieramy F6).
  • Jeśli tylko część metody wykorzystuje zewnętrzne elementy innej klasy to możemy zastosować na tym kawałku Extract Method (zaznaczamy interesujący nas fragment kodu i klikamy kombinację Ctrl+Alt+M).
  • Natomiast kiedy metoda korzysta z elementów wielu różnych klas to najlepiej zidentyfikować tą najbardziej używaną i tam ją przenieść. Można również podzielić daną metodę na wiele mniejszych i poprzenosić wydzielone kawałki do odpowiednich klas.

Aby naprawić code smell o nazwie feature envy wystarczy problematyczną metodę przenieść do klasy, z której elementów ona najwięcej korzysta
Aby naprawić code smell o nazwie feature envy wystarczy problematyczną metodę przenieść do tej klasy, z której elementów ona najwięcej korzysta

Oczywiście powyższe mechanizmy pozwolą nam na zachowanie mniejszej duplikacji kodu. Stanie się on lepiej zorganizowany, a przez to czytelniejszy (metody korzystające z danych będą bliżej nich). Czasami jednak może zdarzyć się sytuacja, że trzeba zerwać z wyżej wymienionymi porządkami z racji np. wykorzystania danego wzorca projektowego. Nic nie jest wyryte w kamieniu i elastyczne podejście paradoksalnie może polepszyć korzystanie z takiego kodu poprzez wprowadzenie feature envy.

Podsumowanie

Pozbycie się feature envy pozwala nam na stworzenie czytelniejszego kodu. Oczywiście taka lokalna refaktoryzacja jest jak najbardziej wskazana. Jednak warto się zastanowić czy zastany problem nie jest konsekwencją błędów popełnionych na wyższym poziomie. Z dużym prawdopodobieństwem dojdziemy do wniosku, że to nasz model kuleje co właśnie powoduje takie “smrodki” jak chociażbym przytoczony w tym artykule feature envy.