Co to jest kod „zazdrości funkcji” i dlaczego uważa się go za zapach kodu?


53

To pytanie na temat SO mówi o poprawieniu tego, co według OP jest kodem zazdrości funkcji . Innym przykładem, w którym widziałem cytowanie tej fajnej frazy, jest ostatnio udzielona odpowiedź tutaj w programmers.SE. Chociaż dodałem komentarz do tej odpowiedzi, prosząc o informacje, które - jak sądzę - byłyby przydatne dla programistów po pytaniach i odpowiedziach, aby zrozumieć, co oznacza termin „zazdrość o funkcje” . W razie potrzeby edytuj dodatkowe tagi.


Odpowiedzi:


88

Zazdrość o cechy to termin używany do opisania sytuacji, w której jeden obiekt trafia na pola innego obiektu w celu wykonania jakiegoś obliczenia lub podjęcia decyzji, zamiast prosić obiekt o wykonanie obliczeń.

Jako trywialny przykład rozważ klasę reprezentującą prostokąt. Użytkownik prostokąta może potrzebować znać jego obszar. Programista może ujawnić widthi heightwypełnić pola, a następnie wykonać obliczenia poza Rectangleklasą. Ewentualnie Rectanglemógłby zachować widthi heightpól prywatnych i zapewnić getAreametodę. Jest to prawdopodobnie lepsze podejście.

Problem z pierwszą sytuacją i powodem, dla którego jest uważany za zapach kodu, jest taki, że przerywa on enkapsulację.

Zasadniczo, za każdym razem, gdy często korzystasz z pól innej klasy do wykonywania dowolnej logiki lub obliczeń, rozważ przeniesienie tej logiki do metody w samej klasie.


7
+1, chociaż twój przykład nie jest realistyczny, ponieważ przydatna klasa Rectangle zazwyczaj ujawnia również pola szerokości i wysokości.
Doc Brown,

2
I chociaż złamanie enkapsulacji może nastąpić razem z „Envirismem cech”, w większości rzeczywistych przykładów, jakie do tej pory widziałem, prawdopodobnie tak nie było. Zdarza się to bardziej w sytuacjach „hej, muszę obliczyć niektóre rzeczy tylko w kodzie przy użyciu tego obiektu i nie jestem pewien, czy mogę dotknąć implementacji tego obiektu / czy powinniśmy powierzyć temu obiektowi odpowiedzialność za to obliczenie”. Następnie wykonuje się obliczenia za pomocą pól, które są już odkryte (chociaż prawdopodobnie znacznie czystsza implementacja byłaby możliwa w obrębie obiektu).
Doc Brown

2
@DocBrown Wyobraź sobie prostokąt narysowany na powierzchni torusa, stożka lub kuli. Jeśli moja biblioteka rysowania kształtów tworzy obiekty, które są w stanie uzyskać prawidłowe wyniki w takich kontekstach, głupotą byłoby nie pozostawić ich do obliczenia własnych obszarów - w dowolnym kontekście.
itsbruce

1
@OskarN .: definicji mówimy o funkcji, które potrzebne. Są oczywiście potrzebne, jeśli inne klasy ponownie je wdrażają.
Aaronaught

1
@OskarN .: to zależy; czasami decyzja jest jasna, czasem kwestia gustu, a najczęściej kwestia doświadczenia. W twoim artykule istnieją dobre powody, dla których Scott Meyers pisze „ czasami mniej znaczy więcej” i że zajęło mu lata, aby zrozumieć, kiedy nie zastosować swojego „algorytmu do decydowania, kiedy należy wprowadzić funkcję członka”.
Doc Brown

1

Może się zdarzyć, że użycie innych metod klasy / struct będzie w porządku - gdy twoja klasa / struktura jest pojemnikiem na dane. Zwykle niewiele można zrobić z tymi danymi bez kontekstu zewnętrznego.

Takie klasy mogą nadal zawierać pewną wewnętrzną logikę, ale częściej są używane jako kontenery:

class YourUid {
 public:
  YourUid(int id_in_workplace_, int id_in_living_place_, DB* FBI_database, int id_in_FBI_database);
  bool IsInvalidWorker() const { return id_in_workplace == consts::invalid_id_in_workplace; }
  bool CanMessWith() const { return !FBI_database_.is_cool(id_in_FBI_database_); }
  int id_in_workplace;
  int id_in_living_place;
 private:
  int id_in_FBI_database_;
  const DB* FBI_database_;
};

@jhewlett w swojej odpowiedzi odwołuje się do tego artykułu, aby udowodnić, że nie powinieneś intensywnie wykorzystywać innych członków klasy, ale istnieje inny kod pachnący sytuacją opisaną tam z rzecznikami mojego przykładu:

Długa lista parametrów. Ogranicz liczbę parametrów potrzebnych w danej metodzie lub użyj obiektu, aby połączyć parametry.


1
Jak to odpowiada na zadane pytanie?
komar

@gnat Pytanie dotyczy tego, dlaczego uważa się go za „zapach kodu”. jhewlett daje literę A ze zbyt ogólnymi założeniami zakwestionowanymi w komentarzach. Moja odpowiedź to 2 centy, aby odróżnić „zapach kodu” od normalnej praktyki.
Ryga
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.