Dlaczego użycie spójników w nazwach metod jest konwencją niewłaściwego nazewnictwa? [Zamknięte]

12

W moim zespole ściśle współpracujemy z kilkoma architektami oprogramowania. Zatwierdzają wszystkie decyzje projektowe naszych projektów, dokonują przeglądów kodu itp.

Nasze projekty składają się głównie z funkcji zaplecza implementowanych w PHP przy użyciu frameworka Symfony 2. Tak więc składniowo kod, konwencje nazewnictwa i struktura projektu wyglądają prawie identycznie jak wyglądałaby Java (Symfony 2 zachęca do takiej struktury). Wspominam o tym, ponieważ w naszym przypadku obowiązują również konwencje specyficzne dla języka Java (jeśli to możliwe).

Niedawno zaproponował, że znajdę coś bardzo dziwnego: wszystkie metody powinny mieć spójników w nazwie np getEntityOrNull, setValueOrExceptionetc.

Taka konwencja nazewnictwa wydaje mi się bardzo błędna, ale nie mogę wymyślić żadnych konkretnych argumentów ani artykułów / stron internetowych, które by to kwestionowały.

Wymyśliłem tylko:

  • takie informacje powinny znajdować się w adnotacjach metody, takich jak @returnlub@throws
  • użycie koniunkcji („i”, „lub” itd.) w nazwach metod zwykle sugeruje, że zasada pojedynczej odpowiedzialności nie jest właściwie przestrzegana

Jakie są inne konkretne argumenty przeciwko tej konwencji nazewnictwa?

Radu Murzea
źródło
generalnie nie możesz
komara
5
the use of conjunctions ("and", "or" etc.) in method names usually suggest that the Single Responsibility Principle is not properly respectedNie dzieje się tak w przypadku przykładów, które wymieniłeś, w których koniunkcja służy do wyjaśnienia mechanizmu wykorzystywanego do obsługi awarii, a nie do wskazania, że ​​może zrobić coś takiego. Nawet najbardziej wąsko zdefiniowana funkcja może mieć uzasadnione warunki awarii, np. Pęknięcie pustego stosu.
Doval
4
Rozważ: (1) użycie „opcjonalnego” zamiast „lub zerowego”. „GetOptionalEntity” brzmi dla mnie lepiej niż „GetEntityOrNull”. (2) biblioteka klas podstawowych .NET stosuje konwencję, że jeśli masz dwie metody, które różnią się tylko tym, co wyrzucają, nazwij tę, która nie może rzucać „TryBlah”. Na przykład, Int32.TryParsei Int32.Parse- oba parsują ciąg znaków na liczbę całkowitą, ale pierwsza zwraca wartość logiczną wskazującą sukces, a druga powoduje niepowodzenie.
Eric Lippert,
Nie użyłbym sufiksu dla wariantu rzucania, ale użyłbym jednego dla wariantu zwracającego wartość zerową. Może być Try..., ...OrNull, ...OrDefault. @EricLippert To nie jedyna konwencja w .net. Rozważmy SingleVs. SingleOrDefault, który jest bardzo blisko do OrNullPO sugeruje.
CodesInChaos

Odpowiedzi:

11

Prawdopodobnie robią to z powodu konfliktów nazw. Zakładam, że nie można nazwać dwóch metod getEntity, z których jedna może zgłaszać wyjątek, a druga zwraca null. Dlatego musisz odpowiednio je nazwać.

Ja, na przykład, nie podoba mi się praktyka posiadania wielu różnych sposobów wywoływania tej samej metody, chyba że dokonuje pewnych zmian, które może wykonać tylko ta konkretna klasa.

Innymi słowy, jeśli getValueOrNullpo prostu dzwoni getValueOrException, przechwytuje wyjątek, a w takim przypadku wraca null, może to zrobić osoba dzwoniąca. Zaśmieca klasę metodami, które tak naprawdę nie wnoszą nic przydatnego. Wolałbym raczej getValuei wiem, że generuje to wyjątek. Co więcej, wolałbym wiedzieć, że wszystkie metody potencjalnie generują wyjątki, a żadna z nich nie zwraca nullzamiast tego, aby zachowanie było jednolite przez cały mój projekt, lub odwrotnie, wszystkie potencjalnie powracają null, i wiem, że osoba dzwoniąca musiałaby zgłosić wyjątek, jeśli były pożądane.

Jednak prawdą jest również to, że nie jesteś za to odpowiedzialny. Moja rada to wychowanie tego, ale nie przejmuj się drobiazgami. Ostatecznie odpowiedzialność za takie konwencje nazewnictwa spoczywa na ich barkach, niezależnie od tego, czy przyjmą one twoją radę, a ponieważ są to ich osły na linii, uważam, że moim przywilejem jest odmawianie, moim skromnym zdaniem.

Neil
źródło
Jeśli musiałeś wybrać tylko jeden, lepiej jest zwrócić null(lub jeszcze lepiej, typ Opcjonalny / Może), ponieważ rzucanie jest stosunkowo drogie. Pisanie pomocnika, który sprawdza, czy wartość jest nieprawidłowa i rzuca, nie powoduje dużego obciążenia. Jednak jeśli chcesz mieć wersję bez rzucania, przełknięcie wyjątku nie zwróci ci wydajności, którą rzuciłeś.
Doval
1
@Doval Dobra uwaga i, co ważniejsze, wyjątki powinny być wyjątkowe . Jeśli często rzucasz wyjątki, nie używasz ich właściwie. Jedynym problemem związanym ze zwrotem nulljest fakt, że nullw niektórych przypadkach może on być prawidłowym zwrotem, dlatego w takich przypadkach należy odstąpić od normy i wrzucić wyjątek.
Neil
3

Chociaż użycie koniunkcji często wskazuje na naruszenie SRP, w tym przypadku jest to po prostu wskazanie wartości zwracanej algebraicznego typu danych biednego człowieka, który może być jedną z dwóch wartości albo wartością null„sukcesu”.

Używają pewnego rodzaju zapisu węgierskiego, aby zrekompensować słabości w systemie typów, a mianowicie brak typów, które nie mają wartości zerowej. Innymi słowy, w @returnadnotacji nie ma możliwości określenia, że funkcja nigdy nie powróci null, i odwrotnie, w @returnadnotacji nie ma możliwości określenia, że funkcja może zwrócić null.

Ponadto uważam, że @throwsadnotacje nie są obowiązkowe w php, więc brak adnotacji nie oznacza braku wyjątku, chociaż lepiej to rozwiązać, wprowadzając adnotację w twoim przewodniku po stylu.

Biorąc pod uwagę ograniczenia języka, którego używasz, nie jest to styl całkowicie nieracjonalny.

Karl Bielefeldt
źródło
2

W moim kodzie czasami tworzę pary metod o nazwach takich jak getEntity () i getEntityOrNull (). Nazwa wyjaśnia oczekiwane zachowanie. Jeśli getEntity () nie znajdzie żadnej encji, zgłoszony zostanie wyjątek. getEntityOrNull () zwróci null.

W ten sposób kod wywołujący staje się nieco wyraźniejszy. Jeśli kod wywołujący musi mieć encję, getEntity załatwi sprawę. Jeśli encja jest czymś opcjonalnym, to getEntityOrNull jest metodą z wyboru.

To samo można osiągnąć za pomocą jednej metody, ale to przenosi część obciążenia na program wywołujący. Zawsze musisz przetestować na wartość zerową lub potrzebujesz bloku try / catch. Tak czy inaczej jest to dodatkowy kod, który musi być duplikowany przy każdym wywołaniu metody.

Jeśli twoi architekci nie używają tego rodzaju par metod, to tak, kwestionowałbym potrzebę sufiksu.

Nigdy tak naprawdę nie widziałem metody setValueOrException. Nie mogę wymyślić dobrego wspólnego przypadku użycia.

Możesz rozważyć pytanie architektów, dlaczego. Ci, których znam, zawsze chętnie wyjaśniają swoje decyzje. Często z bardzo szczegółowymi (a czasem nawet dręczącymi) szczegółami.

Cerad
źródło
To, że getEntity zgłosi wyjątek w przypadku niepowodzenia, nie jest dla mnie jasne, spodziewałbym się prostej wartości NULL.
Elise van Looij,
1

Twoje dwa argumenty są trafne. Ale jeśli to oni decydują o konwencji nazewnictwa, staraj się nie czuć się tak źle, że jest to coś, z czym się nie zgadzasz.

Podczas gdy jesteś przy tym, powinieneś przekonać ich, aby nie używali części „get” i „set”, chyba że te metody faktycznie ustawiają bezpośrednio lub pobierają zmienną składową.

Eben
źródło