Mam kłopoty. Pracuję w repozytorium, które dokonuje wielu zmian w bazie danych w ramach swoich funkcji.
Funkcja, z którą mam do czynienia, zwraca identyfikatory odpowiedzi (ale z transformacji, a nie z jakiejkolwiek akcji bazy danych). Jednak jako efekt uboczny dodaje obiekt zawierający te responseIds do bazy danych.
Więc powinienem go nazwać:
-
getResponseIds
: Podświetla zwracane wartości. To bardzo funkcjonalny sposób myślenia, ale oczywiście jeśli mam funkcjępostToDB
, nie ma sensu używaćgetStatusOfPost
-
addResponseIdToDB
: Podkreśla to efekt uboczny, chociaż naprawdę myślę, że wiele moich funkcji działa tylko na bazie danych (i zwykle niczego nie zwraca) -
getAndAddResponseIdsToDB
: bardzo pouczające, ale bardzo długie.
Jakie są wady i zalety powyższych sugestii? A może sam możesz zaproponować lepszą sugestię?
Komentarze
Odpowiedź
Nazwa funkcji, która zawiera jest na złym poziomie abstrakcji .
Skłaniam się ku addResponseIdToDB()
, ponieważ w innym przypadku „efekt uboczny” jest całkowitym zaskoczeniem. Jednak:
responseIds = addResponseIdToDB();
nikogo nie zaskakuje.
Zasada podziału odpowiedzialności za kwerendy poleceń twierdzi, że nie powinien to być jedyny sposób uzyskania obiektu responseId. Powinno być również zapytanie, które nie zmienia bazy danych, która może pobrać ten obiekt.
W przeciwieństwie do Bertranda Meyera , nie sądzę, że oznacza to, że add musi zwrócić void. Oznacza to, że powinno istnieć równoważne czyste zapytanie i być łatwe do znalezienia, aby baza danych nie została niepotrzebnie nadużywana przez użycie zapytań zmieniających stan.
Biorąc pod uwagę, że getResponseIds()
powinno istnieć i nie komunikować się z bazą danych, najlepszą nazwą metody, która obsługuje oba te elementy, jest w rzeczywistości addToDB(getResponseId())
. Ale to tylko wtedy, gdy chcesz uzyskać całą funkcjonalną kompozycję na ten temat.
Komentarze
- Dodając do tego, co zostało powiedziane, ale dodając słowo, które nie ' nie zostało użyte, powiedziałbym, że ” i ” jest odpowiednie, gdy funkcja wykonuje coś, co jest atomowe . Jeśli istnieje korzyść, którą można uzyskać z dwóch rzeczy zachodzących atomowo / razem / naraz, należy wyraźnie określić, czym te dwie rzeczy są w funkcji imię jest dobre. Ogólnie zgadzam się z pierwszym stwierdzeniem, ale nie zgadzam się bez żadnych zastrzeżeń.
- ” … nikogo nie pozostawia zaskoczony. „. Nie zgadzam się, ' jestem zaskoczony, że zmienna logiczna nazywa się
responseIds
i wtedy muszę zmienić sposób myślenia, aby zdać sobie sprawę, że to dodaje i robi wszystko w jednym. Ale nie zgadzam się z @tintintong, którygetAndAddResponseIdsToDB
jest za długi; jest ' mniej więcej w połowie długości wielu moich nazw funkcji. Jeśli funkcja robi dwie rzeczy, powiedz to w jej nazwie. - @Luaan OK, co zamierzasz zmienić nazwę
getAndIncrement
na to?otherIncrement
? - @Luaan Więc jaką wartość zwraca
Increment
, wartość przed inkrementacją czy po inkrementacji? ' nie jest jasne, co by to było bez zagłębiania się w dokumentację.Myślę, żeincrementAndGet
igetAndIncrement
są znacznie lepszymi nazwami metod, co moim zdaniem jest dobrym przykładem dla ” AND ” w nazwach metod, przynajmniej w określonym przypadku metod, które mają skutki uboczne, które mogą wpływać na zwracaną wartość. - @Luaan Kiedy mówisz ” Increment zwraca zwiększoną wartość „, masz na myśli wartość przed przyrostem? Rozumiem, na początku cię źle zrozumiałem … co jest w rzeczywistości doskonałym przykładem, dlaczego
getAndIncrement
iincrementAndGet
to lepsze nazwy niż tylkoincrement
, nawet rozważane indywidualnie
Odpowiedź
Jak wspominali inni, użycie and
w nazwie funkcji automatycznie implikuje, że funkcja wykonuje co najmniej dwie rzeczy, co zwykle oznacza, że robi za dużo lub robi coś w niewłaściwym miejscu.
Użycie klauzuli and
w nazwie funkcji, jednak z mojego doświadczenia wynika, że może mieć sens, gdy w pewnym przepływie są kroki, które muszą być wykonywane po kolei lub gdy całe obliczenie stanie się sensowne.
W obliczeniach numerycznych może to mieć wiele sensu:
normalizeAndInvert(Matrix m)
To znaczy, kto wie, prawda? Jeśli potrzebujesz obliczyć … powiedzmy, trajektorie oświetlenia w grafice komputerowej i na certyfikacie na etapie musisz znormalizować i odwrócić pewną macierz i ciągle piszesz:
m = normalize(m)
, a po nim invert(m)
, jako prosty przykład, wprowadzający abstrakcję normalizacji i odwracania, może być dobre z punktu widzenia czytelności.
Mówienie semantycznie, rzeczy takie jak divideAndConquer()
etc, prawdopodobnie odradza się jawne zapisywanie, ale cóż, And
jest w zasadzie konieczne.
Komentarze
- Funkcje regularnie wykonują więcej niż jedną rzecz, ale powinny to być małe rzeczy, które składają się na jedną wielką rzecz, która ' ma znaczenie na wyższym poziomie.
normalizeAndInvert
może byćcomputeLighting
, adivideAndConquer
może byćapplyMachiavelli
- Oczywiście 🙂 Po prostu stwierdzam, że najpierw utworzono funkcję z ” i ” w nazwie może być naturalną abstrakcją opartą na określonym kontekście. Refaktoryzacja za pomocą metody ” Zmień nazwę metody ” powinna nastąpić bezpośrednio po;)
- @BrunoOliveira Z wyjątkiem tego, że czasami te dwa kroki są same w sobie są składnikiem wielu rzeczy, zmiana nazwy nie jest ' t właściwym podejściem. Powinien być rzadki, ale nigdy go nie używasz, oznacza to, że ' powtarzasz się ponownie.
Odpowiedź
Powiedziałbym, że ogólnie jest w porządku, ale nie jest akceptowalny we wszystkich przypadkach.
Na przykład można argumentować przeciwko and
w nazwie funkcji opartej na zasadzie pojedynczej odpowiedzialności , czyli S w SOLID – ponieważ and
może oznaczać wiele obowiązków. Jeśli and
naprawdę oznacza, że funkcja robi dwie rzeczy, prawdopodobnie zechcesz dokładnie przemyśleć, co się dzieje.
Przykład biblioteki, która wykorzystuje and
w nazwach funkcji, które można znaleźć w Java „s współbieżności i tutaj and
jest w rzeczywistości bardzo ważną częścią tego, co się dzieje i ściśle pasuje do tego, co opisujesz w swoim poście, gdzie stan został zmieniony, i stan został zwrócony. Tak więc jest kilka osób ( i niektórych przypadkach użycia) tam, gdzie jest to uznane za dopuszczalne.
Komentarze
- ”
and
może oznaczać wiele obowiązków „. I w tym przypadku rzeczywiście na to wskazuje. Funkcja pobiera skądś identyfikatory odpowiedzi, zapisuje je w bazie danych i zwraca je. Potrzeba tego ” i ” rzeczywiście powinna przynajmniej wzbudzić w OP, że potrzebne są dwie funkcje: jedna do uzyskania identyfikatorów i jeden do zapisania ich w bazie danych. - Chociaż zgadzam się, że
and
to zapach kodu, podstawowe zachowanie wydaje się prawidłowe: generalnie nie jest to złe pomysł, aby zwrócić jakąś dodatkową (e) wartość (y) z metody, która okazała się być niezbędna (pośrednia), jest wynikiem realizacji jej głównej funkcji. Jeśli główną funkcją tej metody jest dodawanie identyfikatorów odpowiedzi do bazy danych, dodatkowo zwracanie identyfikatorów, które dodała do obiektu wywołującego, jest po prostu schludną, łatwą w użyciu cechą metody. - Nie ' Nie sądzę, żeby to koniecznie naruszało SRP. Zawsze będziesz potrzebować funkcji wykonujących wiele rzeczy. Ważne jest, aby te funkcje wywoływały inną funkcję dla każdej rzeczy, którą chcą, zamiast bezpośrednio zawierać wymagany kod.
- Jeśli funkcja wykonuje dwie rzeczy, nazwa powinna to odzwierciedlać.
Odpowiedź
Rzeczywiście, to „trudne pytanie, o czym może świadczyć wiele komentarzy. Ludzie wydają się mieć sprzeczne opinie i rady na dobre imię.
Chciałbym dodać moje 2 centy do tego 2-miesięcznego wątku, ponieważ myślę, że mogę dodać więcej kolorów do tego, co już zostało zasugerowane.
Nazywanie to proces
Wszystko to przypomina mi doskonały przewodnik w 6 krokach: Nazywanie jako proces .
Zła nazwa funkcji to taka, która jest zaskakująca i zdajesz sobie sprawę, że nie możesz ufać. Dobre nazewnictwo jest trudne do uzyskania przy pierwszym ujęciu. Wraz z doświadczeniem staje się łatwiejsze.
6 iteracyjnych kroków do zbudowania dobrego imienia
- Zastąp zaskakującą nazwę oczywistym nonsensem jak
appleSauce()
. Brzmi głupio, ale jest tymczasowe i jasno pokazuje, że tej nazwie nie można ufać. - Zdobądź uczciwe imię , na podstawie tego, co rozumiesz z działania funkcji. Powiedzmy, że jeszcze nie zrozumiałeś wstawiania w części DB,
getResponseIdsAndProbablyUseDb
będzie opcją. - Pobierz do całkowicie uczciwego , więc nazwa funkcji mówi wszystko, co robi funkcja (
getAndAddResponseIdsToDB
lubgetResponsesButAlsoAddCacheOfTheResponsesToTheDb
z @Fattie to świetne przykłady) - Get to „robi właściwą rzecz” czyli w zasadzie część, w której dzielisz swoją funkcję na „I”. W rzeczywistości masz
getResponseIds
iaddResponseIdsToDb
. - Uzyskaj nazwę „Odkrywanie intencji” , która rozwiązuje problem „Zawsze chcę uzyskać identyfikator odpowiedzi I wstawione do DB po tym, jak to zrobię „. Przestań myśleć o szczegółach implementacji i zbuduj abstrakcję, która używa 2 najmniejszych funkcji do zbudowania czegoś innego. To jest wyższy poziom abstrakcji wspomniany przez @candied_orange. Dla e xample
createResponseIds
może to zrobić i będzie składemgetResponseIds
iaddResponseIdsToDb
. - Przejdź do abstrakcji domeny . To trudne, to zależy od Twojej firmy. Potrzeba czasu, aby dobrze zrozumieć język biznesowy. W końcu może się okazać, że koncepcja
Response
iResponse.createIds()
miałaby sens. A możeResponseId
jest czymś wartościowym i musiałbyś mieć fabrykę do stworzenia wielu. Wstawienie do bazy danych byłoby szczegółem implementacji repozytorium itp. Tak, projekt byłby bardziej abstrakcyjny. Byłoby bogatsze i pozwoliłoby ci wyrazić więcej. Nikt spoza Twojego zespołu nie może Ci powiedzieć, jaka powinna być poprawna abstrakcja domeny w Twojej sytuacji. To zależy .
W twoim przypadku masz już zorientowane 1 i 2, więc prawdopodobnie powinieneś przynajmniej przejść do 3 (użyj „AND”) lub dalej. Ale pójście dalej to nie tylko kwestia nazewnictwa, faktycznie rozdzielisz obowiązki.
Zatem różne sugestie tutaj są ważne
Zasadniczo:
- Tak, zaskakujące nazwy funkcji są okropne i nikt nie chce się tym zajmować
- Tak, „AND” jest dopuszczalne w nazwie funkcji, ponieważ jest lepsze niż myląca nazwa
- Tak, poziom abstrakcji jest pokrewną koncepcją i ma znaczenie
Nie musisz od razu przechodzić do etapu 6, dobrze jest pozostać na etap 2, 3 lub 4, dopóki nie będziesz wiedział lepiej!
Mam nadzieję, że byłoby to pomocne w przedstawieniu innego spojrzenia na to, co wygląda na sprzeczne porady. Wierzę, że wszyscy dążą do tego samego celu ( nazwy niezbyt zaskakujące), ale zatrzymują się na różnych etapach, w oparciu o własne doświadczenie.
Z przyjemnością odpowiem, jeśli masz jakiekolwiek pytania 🙂
Odpowiedź
Twoja funkcja robi dwie rzeczy:
- Pobiera zestaw identyfikatorów poprzez transformację i zwraca je do wywołującego,
- Zapisuje ten zestaw identyfikatorów w bazie danych.
Pamiętaj o zasadzie pojedynczej odpowiedzialności: powinieneś dążyć do funkcji mieć jedną odpowiedzialność, a nie dwie. Masz dwie obowiązki, więc masz dwie funkcje:
getResponseIds
– Pobiera zestaw identyfikatorów poprzez transformację i zwraca je do dzwoniącego
addResponseIdToDB
– Pobiera zestaw identyfikatorów i zapisuje je w bazie danych.
I cały problem, jak nazwać pojedynczą funkcję z wieloma obowiązkami, znika, a pokusa umieszczania and
w nazwach funkcji również znika.
Jako dodatkowy bonus, ponieważ ta sama funkcja nie jest już odpowiedzialna za dwie niezwiązane ze sobą akcje, getResponseIds
może zostać przeniesione z kodu repozytorium (gdzie nie należy ponieważ nie wykonuje żadnej czynności związanej z bazą danych), do osobnej klasy / modułu na poziomie biznesowym itp.
Komentarze
- Że ' z pewnością jest prawdą, ale zdarza się, że powtarzasz fragment kodu za pomocą tych dwóch metod SRP wiele razy, więc prawdopodobnie powinieneś napisać trywialną metodę, aby to zrobić, aby WYTRZYMAĆ, nie powinieneś ' t ty?
- @maaartinus, jeśli zauważysz, że wywołujesz te dwie metody w wielu miejscach, prawdopodobnie masz problem z brakiem spójności w kodzie. Utworzenie funkcji ” DRY ” następnie maskuje ten brak spójności.
Odpowiedź
Posiadanie nazwy funkcji złożonej jest dopuszczalne, więc używany schemat nazewnictwa zależy od kontekstu. Są puryści, którzy powiedzą ci, żebyś to zlikwidował, ale ja będę argumentował inaczej.
Są dwa powody, dla których warto unikać takich rzeczy:
- Czystość – funkcja który robi dwie rzeczy, powinien zostać przekonwertowany na dwie funkcje, z których każda wykonuje jedną rzecz.
- Rozmiar leksykalny –
bigUglyCompositeFunctionName
jest trudny do odczytania.
Argument czystości jest zazwyczaj tym, na którym się koncentrujemy. Rozbijanie funkcji jest dobrą rzeczą, jako ogólną ogólną heurystykę. Pomaga uporządkować to, co się dzieje, ułatwiając zrozumienie. Jest mniej prawdopodobne, że wykonasz „sprytne” sztuczki ze współdzieleniem zmiennych, które prowadzą do sprzężenia między tymi dwoma zachowaniami.
Więc pytanie, które należy sobie zadać, brzmi: „Czy mimo wszystko powinienem to zrobić?” Mówię, że zrywanie rzeczy to niejasna heurystyka, więc naprawdę potrzebujesz tylko przyzwoitego argumentu, aby się temu przeciwstawić.
Jednym z głównych powodów jest to, że korzystne jest myślenie o tych dwóch operacjach jako jednej. Ostateczny przykład tego można znaleźć w operacjach atomowych: compare_and_set
. compare_and_set
to fundamentalny kamień węgielny atomistyki (który jest sposobem na wielowątkowość bez blokad), który jest na tyle skuteczny, że wielu jest skłonnych myśleć o nim jako o kamień węgielny. W tej nazwie jest „i”. Jest ku temu bardzo dobry powód. Cały sens tej operacji polega na tym, że porównuje i ustawia jako jedną niepodzielną operację. Jeśli podzielisz go na compare()
i set()
, pokonasz cały powód, dla którego funkcja istniała w pierwszej kolejności, ponieważ dwa compares()
może wystąpić wstecz przed set()
s.
Widzimy to również w wydajności. Moim ulubionym przykładem jest fastInvSqrt . To słynny algorytm firmy Quake, który oblicza 1 / sqrt (x). Łączymy operacje „odwrotne” i „pierwiastek kwadratowy”, ponieważ daje to nam ogromny wzrost wydajności. Wykonują aproksymację Newtona, która wykonuje obie operacje w jednym kroku (i zdarza się, że robią to w matematyce całkowitej, a nie zmiennoprzecinkowej, co miało znaczenie w epoce). Gdybyś miał wykonać inverse(sqrt(x))
, byłoby to znacznie wolniejsze!
Czasami wynik jest wyraźniejszy. Napisałem kilka interfejsów API obejmujących wątkowanie, w których trzeba bardzo uważać na takie rzeczy jak zakleszczenia. Nie chciałem, aby mój użytkownik był świadomy wewnętrznych szczegółów implementacji (zwłaszcza, że mógłbym je zmienić), więc napisałem API z kilka funkcji „i”, które uniemożliwiły użytkownikowi kiedykolwiek utrzymywanie blokady dla więcej niż jednego wywołania funkcji. Oznacza to, że nigdy nie musieli wiedzieć, jak radzę sobie z wielowątkową synchronizacją pod maską. W rzeczywistości większość moich użytkowników nie była nawet świadoma, że znajdują się w środowisku wielowątkowym!
Więc chociaż ogólną zasadą jest rozwiązywanie problemów, zawsze może istnieć powód, aby połączyć je razem. Na przykład , czy użytkownik może złamać Twoją architekturę, dodając ją do bazy danych wiele razy bez „pobiera” pomiędzy nimi? Jeśli każda z odpowiedzi zarejestrowanych w bazie danych musi mieć unikalny identyfikator, możesz mieć kłopoty, jeśli użytkownik będzie musiał to zrobić. Nie. Podobnie, czy kiedykolwiek chciałbyś pozwolić użytkownikowi „pobrać” bez rejestrowania wyników w bazie danych? Jeśli odpowiedź brzmi „tak”, podziel je, aby użytkownik miał dostęp do funkcji „pobierz”. Jednak jeśli bezpieczeństwo twojej aplikacji jest zepsute, jeśli użytkownik może „pobrać” bez zapisywania wyniku w DB, naprawdę powinieneś trzymać funkcje razem.
Jeśli chodzi o kwestie leksykalne, nazwa funkcji powinna opisywać, co użytkownik musi o tym wiedzieć. Zacznijmy od części „pobierz”.Usunięcie „get” z nazwy funkcji jest dość łatwe, ponieważ we wszystkich przykładach będzie widoczne przypisanie: int id = addResponseIdToDB()
„. We wszystkich miejscach, w których funkcja jest używana, zakończysz udokumentowanie faktu, że funkcja zwróciła wartość.
Podobnie „add” może być opcjonalne. Używamy terminu „efekt uboczny” jako obejmującego wszystko terminu, ale istnieją różne jego odcienie. Jeśli wpisy bazy danych są jedynie dziennikiem, może nie być powodu, aby go podkreślać. Nigdy nie widzimy funkcji takich jak playMusicAndSendPersonalInformationToOurCorporateServers
. To po prostu playMusic
, a jeśli masz szczęście, w dokumentacji może być wzmianka o połączeniu z gniazdem internetowym. Z drugiej strony, jeśli oczekuje się, że użytkownicy będą wywoływać tę funkcję w celu dodawania rzeczy do bazy danych, wtedy „add” jest niezbędne. Nie wyjmuj tego.
Teraz napisałem wiele powodów, aby robić każdą możliwą kombinację tego, o co prosisz. Celowo nie odpowiedziałem na pytanie, ponieważ trzeba dokonać wyboru. Nie jest to reguła do naśladowania. Przeprojektowujesz API.
Biorąc to pod uwagę, instynktownie myślę, że addResponseIdToDB będzie prawdopodobnie najlepszą odpowiedzią. W większości przypadków część „pobierz” jest na tyle oczywistym efektem ubocznym, że nie generuje dodatkowego szumu spowodowanego wpisywaniem jej wszędzie. Jest jednak kilka miejsc, w których mógłbym uznać ją za ważną:
- Jeśli polecenie „get” jest drogie – jeśli musisz wykonać polecenie „get”, które obejmuje pobranie czegoś przez Internet, a następnie dodanie tego do lokalnej bazy danych pamięci podręcznej, zdecydowanie ważne jest polecenie „get”. To jest rzecz, którą próbuje zrobić użytkownik.
- Jeśli chcesz wyjaśnić, że użytkownik musi zwrócić uwagę na wartość. Jeśli użytkownik chce użyć zmiennej, zda sobie sprawę, że API zwraca ją i użyje jej. Jednak chcesz uważać na użytkownika, który nie wie, że tego potrzebuje. Na przykład, jeśli musisz później „zamknąć” tę operację za pomocą identyfikatora, aby zwolnić pamięć, możesz zwrócić uwagę na fakt, że coś robisz. W takich przypadkach możesz spojrzeć na czasownik inny niż „get”. „get” często implikuje idempotentne funkcje (ponowne wywołanie go nie robi nic). Jeśli zwraca zasoby, inne czasowniki, takie jak „tworzenie” lub „pobieranie”, są miłe. Ten konkretny mechanizm niepowodzenia jest głównym problemem w C podczas obsługi wyjątków .C nie ma mechanizmu catch / throw C ++, więc opiera się na kodach powrotu. Programiści są znani z tego, że po prostu nie sprawdzają tych kodów powrotu i wpadają w naprawdę złe sytuacje, takie jak przepełnienie bufora z tego powodu.
- Symetria – czasami projektujesz interfejs API tak, aby miał do niego symetrię leksykalną. Ustawiasz słowa tak, aby występowały w parach lub innych wzorach i tworzysz polecenia tak, aby można było je łatwo zidentyfikować wizualnie czy wzorzec był przestrzegany, czy nie. Powiedziałbym, że jest to rzadkie, ale nie jest to niespotykane. Istnieje „powód, dla którego zamykające tagi XML powtarzają nazwę tagu (na przykład < foo > i < / foo >).
Komentarze
- Dla osób, które tego nie robią ' Nie znam matematyki: Zarówno 1 / x, jak i sqrt (x) są raczej powolnymi funkcjami. Używając sprytnych obliczeń, możemy obliczyć 1 / sqrt (x) szybciej niż dzielenie lub pierwiastek kwadratowy. Właściwie o wiele szybciej, że najszybszym sposobem obliczenia sqrt (x) jest obliczenie 1 / sqrt (x) za pomocą sprytnej implementacji i pomnożenie wyniku przez x.
- Tak jak w fizyce, gdzie jednostkami elementarnymi nie są już metry i sekundy, ale sekundy i prędkość światła, ponieważ możemy zmierzyć prędkość światła z większą dokładnością niż długość metra.
Odpowiedź
Co jest najlepsze zamiar tej metody od? Po co dodawać te przekształcone identyfikatory do bazy danych, czy ma to na celu buforowanie? Będę pracować przy tym założeniu.
Wygląda na to, że intencją metody jest po prostu uzyskanie przekształconych identyfikatorów odpowiedzi (albo wykonanie transformacji, albo pobranie ich z pamięci podręcznej), więc nie ma nazwa metody:
getTransformedResponseIds
lub mniej dosłownie getResponseIds()
Metoda o tej nazwie może buforować a może nie, i można to udokumentować, ale nazwa metody nie powinna wiązać Cię z konkretną implementacją; Co jeśli zdecydujesz się przestać używać bazy danych i zamiast tego buforować ją w innym miejscu, np. tymczasowo w pamięci?
Efekty uboczne powinny być tylko efektami ubocznymi, prawdopodobnie powinny być udokumentowane, ale nie powinny tak naprawdę wpływać na główny cel (lub sukces) lub nazwę funkcji. Jeśli pobranie wartości z pamięci podręcznej nie powiedzie się (lub jeśli skonfigurujesz pominięcie pamięci podręcznej), co nie powinno być krytycznym problemem, metoda powinna po prostu ponownie przeliczyć, buforować (lub nie) i zwrócić nową wartość.
Czasami użycie „AND” jest pomocne, aby przekazać intencję, na przykład w metodach Java getAndIncrement
i incrementAndGet
, więc to z pewnością nie jest poza tabelą.
Odpowiedź
Mówisz, że funkcja zwraca coś „z transformacji, a nie z dowolna akcja db ”.
Sugeruje to, że funkcja zachowuje się bardziej jak konstruktor niż getter. Jednak konstruktory również nie powinny” nie powodować efektów ubocznych (dzięki za link, @ MechMK1 ).
Z drugiej strony, metody fabryczne już zakładają pewien stopień bałaganu . Na przykład jedną z motywacji do używania metod fabrycznych jest to, że jest to metoda fabryczna:
Pozwala na bardziej czytelny kod w przypadkach, gdy istnieje wiele konstruktorów, każdy dla inny powód. – wikipedia
Podobnie
Jeśli musisz popracować nad efektami ubocznymi, metoda fabryczna może zostać nazwana w taki sposób, aby było bardziej jasne, jakie są te skutki uboczne. – ruakh
Rozważ uczynienie funkcji metodą fabryczną, używając terminu „zalogowany”, aby powiadomić programistów o pamięci bazy danych:
- Deklaracja:
createLoggedResponseid(...) {...} // log object to db
- Zadzwoń:
responseid = createLoggedResponseid(...);
Komentarze
- Konstruktorzy nie powinni powodować skutków ubocznych
- @ MechMK1 ' zmodyfikowałem, aby usunąć sugestię konstruktora i zapewnić więcej wsparcia dla metody fabrycznej o odpowiedniej nazwie. Daj mi znać, co pomyśl.
persistResponseIds
?getStatusOfPost
🙂responseIds = createResponseIds()
wydaje się jasne i zwięzłe.get()
coś, co wcześniej ' nie istniało, więccreate
jest odpowiednim czasownikiem. Nowo utworzony materiał jest tym, co ' spodziewasz się zwrotu funkcjicreate()
. A może ' brakuje mi czegoś oczywistego?