Gdy metoda ma zbyt wiele parametrów?

Podczas debugowania kodu klienta usług internetowych (w Javie, z jax-WS) natknąłem się na metodę usług internetowych z oszałamiającą ilością 97 parametrów!

Musiałem stworzyć przypadek testowy, który wywołuje tę metodę i zauważyłem kilka rzeczy:

  • asystent kodu / kursor nie skaluje się dobrze. Używam Eclipse, a etykieta na metodzie jest tak szeroka jak ekran i obejmuje kilka linii.
  • musiałem skopiować wartości parametrów z poprzedniego przechwytywania xml i to było praktycznie niemożliwe do zapamiętania "gdzie jestem" - Kiedy miałem kursor umieszczony za przecinkiem i przed wpisaniem jakiejś wartości, często źle zrozumiałem typ danych-wpisałem liczbę całkowitą zamiast ciągu i odwrotnie.
  • nawet po napisaniu wszystkich parametrów, nadal miałem kilka błędów i podpis nie pasował. Niestety Eclipse zaznacza całą linię na czerwono jako mającą błąd, więc znalezienie miejsca błędu zajęło jeszcze więcej czasu : ([6]}

Więc to dało mi do myślenia, co Ty czy jest maksymalna liczba parametrów dla metody? A jeśli mógłbyś zmienić ten podpis usługi internetowej, jak myślisz, jak można go poprawić?

Author: Yoni, 2010-02-11

9 answers

Nie ma wyraźnego limitu, ale czuję się niekomfortowo z więcej niż 3-4 parametrami. AFAIR Wujek Bob Martin w Clean Code poleca max 3.

Istnieje kilka refaktoringów w celu zmniejszenia liczby parametrów metody (zobacz Working Effectively with Legacy Code, Michael Feathers po szczegóły). Przychodzą mi do głowy:

  • enkapsuluje wiele powiązanych parametrów w jeden obiekt (np. zamiast String surName, String firstName, String streetAddress, String phoneNumber przekazuje Person obiekt zawierający te pola)
  • przekazywanie parametrów w konstruktorze lub innych wywołaniach metody przed wywołaniem tej metody
 61
Author: Péter Török,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:09:51

Kiedy musisz pytać, to prawdopodobnie jest ich zbyt wiele.

 30
Author: user151323,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:11:18

Jak wspomina Steve McConnell w Code Complete, złota reguła to 4 + / -3 parametry. Dla przeciętnego człowieka trudno zapamiętać więcej niż 4 parametry, 5-7 powinno być używane tylko w szczególnych przypadkach i nigdy nie należy używać 8 lub więcej.

 12
Author: Ondrej Slinták,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:22:28

Wielki Budda!! 97????

Dobra praktyka zwykle radzi o max. sześć do ośmiu. Oczywiście, ymmv, i może być ważny powód, od czasu do czasu, dla dziewiątego. Ale 97??!!

Kilka myśli ... czy są to po prostu DANE, czy decyzje podejmowane są w oparciu o ich wartości?

Jeśli wiele / większość wpływa na kontrolę przepływu, masz prawie niemożliwy do utrzymania (nawet zrozumiały lub testowalny) "design" (dla małych wartości "design").

Jeśli są to po prostu dane, czy można je pogrupować w struktury i wskaźniki ot te struktury przekazywane?

Czy masz jakąś dokumentację projektową? Może to wyjaśnia, co się dzieje.

No I "Danger, Will Robinson" - każdy, kto otwarcie przejdzie 97 parametrów, może również przekazać dowolną liczbę - nie tak oczywistą - jako zmienne globalne.

P. S Nie wiem jak Eclipse działa na Javie, ale z C / C++, Jeśli umieścisz paramaetery na osobnych liniach

char DoEverything(
        int meaninglessParameterName1,
        char *meaninglessParameterName2,
        ....
        long double *meaninglessParameterName97)
        { return !NULL;}

Eclipse będzie identyfikować linię z zły parametr

 8
Author: Mawg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:17:29

Cóż, jeśli zrobisz z niego obiekt JSON, możesz zawinąć wszystkie 97 (lub więcej) w ten obiekt i wysłać tylko jeden obiekt.

 5
Author: Mark Schultheiss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:12:33

Jeśli jego więcej niż 5-10 parametrów, Utwórz obiekt, który pobierze parametry zamiast tego, może to być wpisany zbiór danych, struktura lub cokolwiek innego.

Zamiast:

Mywebservice.CreateUser(Firstname, LastName, Age,Sex, Haircolor,AmountOfFingers,AmountOfTeeht,Childrens,,,,,,,,,,,,,and so on)

Do:

Dim MyUser as new UserObject
MyUser.Firstname="Stefan"
...and so on...
MyWebservice.CreateUser(UserObject)
 3
Author: Stefan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:10:45

Z własnego doświadczenia wynika, że podpisy metod zaczynają być mylące i trudne do zapamiętania z więcej niż 5 lub 6 parametrami. A jak przekroczysz 10 parametrów to jest po prostu śmieszne.

Te parametry naprawdę muszą być połączone w obiekt (lub mały zestaw obiektów), który przechowuje wszystkie dane. W usługach, z których korzystam, każda operacja usługi zawsze pobiera pojedynczy obiekt żądania i Zwraca pojedynczy obiekt odpowiedzi.

 1
Author: Kaleb Brasee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:14:43

Jeśli chodzi o Usługi internetowe, wolę obsługiwać parametry jako pojedynczy obiekt. Chociaż umowa dotycząca danych może ulec zmianie, Umowa o świadczenie usług nie ulegnie zmianie. To sprawia, że Twoje usługi są bardziej przyszłościowe.

Za wszystko inne jestem za 3 parametrami, a za 5.

 0
Author: John Laffoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-11 14:26:14

Cóż, sugerowałbym przeciążenie metody, aby mieć prostsze implementacje metody. Może to być szczególnie przydatne, jeśli wiele parametrów rzadko się zmienia i można przypisać wartości domyślne. Jeśli jednak pamięć służy, nie sądzę, że można przeciążać wywołanie usługi internetowej (musisz użyć odrębnej nazwy metody).

Innym możliwym rozwiązaniem jest umieszczenie parametrów w jakiejś klasie metadanych, której celem jest przechowywanie parametrów. Uprościłoby to podpis metody. Jednak pod pewnymi względami po prostu przenosisz problem do klasy parametrów. Ale, jeśli parametry mogą być catagorized do tematów ta technika może być stosowany przez wykorzystanie kilku klas metadanych, każda z nich będzie zawarta jako parametr do usługi internetowej. To powinno uprościć rzeczy i pomóc ci ogarnąć tego potwora.

Wreszcie, trudno powiedzieć bez żadnych szczegółów, ale z pewnością wydaje się, że ten kod jest poważnym kandydatem do refaktoryzacja. Nie mam twardej i szybkiej Zasady liczby parametrów dla metody innej niż przyjęcie ogólnej zasady prostoty i czytelności.

 0
Author: Ed Chaparro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-14 02:41:23