2009-06-11 10 views
19

Często mam problem z opisaniem funkcji w zwięzłej nazwie. Zwykle nie stanowi to problemu w funkcjach, które są wykonywane w celu ponownego użycia, ale często duży proces musi zostać podzielony na podfunkcje. Często otrzymują dziwne nazwy, takie jak connectionsToAccessLines lub handleWallVisionSplit lub coś w tym stylu. Podczas gdy te funkcje wykonują tylko jedną rzecz, trudno jest wymyślić dla nich dobre imię, ponieważ tak naprawdę są tylko częścią większego algorytmu.Problemy z wymyślaniem nazw dla funkcji

Co robisz w tej sytuacji? To bardzo frustrujące.

+5

To powinno być wiki. – gnovice

Odpowiedz

17

czasem, jeśli nie można wymyślić dobrej nazwy funkcji jest wskazanie, że funkcja nie ma ładny , ostra ostrość i musi być refaktoryzowana. Jeśli jest to metoda klasowa, być może klasa wymaga również refaktoryzacji.

Ale to jest warte problemów ze znalezieniem najlepszych możliwych nazw, ponieważ czyni twój kod znacznie bardziej zrozumiałym i użytecznym.

Aktualizacja: Wielu autorów inżynierii oprogramowania mówiło o znaczeniu nazewnictwa. Henry F. Ledgard's Programming Proverbs (1975) i Brian Kernighan i P.J. Plaugher's Elements of Programming Style (1978) były wczesne i nadal warte są czytania. Wspaniała wersja Stevena McConnella Code Complete (2nd Edition, 2005) jest nowszym przykładem, poświęcając cały rozdział tematowi.

Elementy stylu programowania były częściowo wzorowane na Strunk and White's Elements of Style, co w rzeczywistości ma zaskakujące znaczenie. Ich nacisk na prostą i zwięzłą prozę ma zastosowanie do naszych technicznych pism i komentarzy (i nazywania), ale zawsze uważałem to za analogiczne do tego, co robimy, kiedy odnawiamy i ulepszamy nasz kod.

+1

Tak. Zdecydowanie się zgadzać. – PeterAllenWebb

+0

Poza czasami nie można podzielić funkcji na części ze względu na wydajność. Na przykład, iteracja przez zestaw i jednoczesne szukanie tych wartości w innym, a gdy zostanie znaleziony usunąć je oba, ale najpierw umieścić je w trzecim zwracanym pojemniku, inaczej: MoveSetUnionToNewSet. Znacznie zwiększyłoby złożoność algorytmiczną, aby podzielić tę funkcję. – rlbond

+0

To prawda, a Strunk i White nie sugerowaliby usuwania słów potrzebnych do znaczenia. "MoveSetUnionToNewSet" z pewnością nie jest zbyt długi w mojej książce, chociaż być może bardziej zrozumiałe byłoby "Set ExtractSetUnion (Set a, Set b)". –

13

Wolę raczej absurdalnie długie nazwy metod w kontekście większego algorytmu, ponieważ zmniejsza to potrzebę patrzenia na implementację funkcji.

Nazwa jak ReadPropertiesFromFileThenWriteToSession jest lepsza niż ReadProps.

+8

Tak, dłuższe nazwy są zdecydowanie lepsze niż krótkie, wieloznaczne nazwy, takie jak Doaction (int id); Ale też nie przesadzaj. Jeśli nie możesz opisać jednym słowem lub krótką frazą, co robi metoda, podziel ją na więcej metod :) –

+1

Powiedziałbym, że problem polega na tym, kiedy chcesz jedną metodę, aby ostatecznie wywołać więcej metod. Metoda 1 wywołuje funkcję DoXAndYIfZ (która zawiera pewne sprawdzanie zmiennych/stanów), która wywołuje X i Y osobno. W takich przypadkach, gdy nie chcesz logiki rozgałęzienia w metodzie wyższego poziomu, nie możesz po prostu "dodać więcej metod" do niej. Twoje imię będzie dłuższe. –

+2

... chociaż generalnie zgadzam się z tobą tylko "gdy masz kłopot z wymyślaniem krótkiej nazwy, po prostu zrób długie imię" jako zastrzeżenie! :) –

0

Twoje funkcje powinny naprawdę informować o tym, co robią! Ale nie w przesadnie gadatliwy sposób. To jest coś, co opanujesz z biegiem czasu, to wymaga trochę praktyki, aby prawidłowo funkcjonować.

Zapoznaj się z artykułem this, aby zapoznać się z pewnymi sprawami, o których pisałem na ten temat od jakiegoś czasu :) Upewnij się, że podszedłeś do other article, który zainspirował mnie do napisania i sprawdzenia komentarzy.

0

Jedną z sugestii z książek Refactoring jest spojrzenie na długi algorytm i w każdym miejscu, w którym czujesz, że jest blok w kodzie, który możesz opisać za pomocą jednego liniowego komentarza, który to refaktor przekształca w prywatną funkcję i użyj tego, co jest w pojedyncza linia jako nazwa funkcji. To może być naprawdę długie, ale jeśli pomoże ci to szybko odczytać algorytm, jest idealnie. Kod kompletny wspomina dobry zakres od 9 do 15 znaków.

I nie martw się, jeśli jest to prywatna funkcja pomocnika refactoring nazwa później ma problemu

2

Ilekroć uderzył w mur, próbując wymienić funkcji lub procedury, wracam i bardzo ciężko myśleć o tym, co Myślę, że tak. Często, jeśli nazwa nie sugeruje się łatwo, jest to wskazówka, że ​​nie zastanawiałem się, co powinna zrobić funkcja lub procedura.

Masz proces, który musi wykonać A, B, C, ..., X, Y i Z; nie możesz nazwać procedury doABCDEFGHIJKLMNOPQRSTUVWXYZ. Musisz znaleźć logiczne grupowanie średniego poziomu (być może kilka warstw grupowań), które dzielą ten proces na wyższy.

Czasami znalezienie właściwej nazwy wymaga przeniesienia kodu tak, aby znajdował się w bardziej logicznych fragmentach.

Kolejną pomocą jest enkapsulacja funkcji/procedur (w zależności od funkcji języka, którego używasz), dzięki czemu nazwa może być krótsza (ponieważ jej nazwa może być interpretowana w kontekście kontenera). Na przykład procedura "openFile" powinna normalnie po prostu otworzyć plik do odczytu; ale w kontekście klasy "UserPrefsFile" może mieć bardziej konkretne znaczenie.

9

Późny, wspaniały Phil Karlton żartobliwie napisał: W informatyce są tylko dwa trudne problemy - nazywanie rzeczy i unieważnianie pamięci podręcznej. Moje doświadczenie skłania mnie do przekonania, że ​​w tym jest wiele prawdy.

Nazywanie rzeczy dobrze jest sztuką tak samo jak nauką, i jako takie nie ma żadnych twardych i szybkich zasad.To powiedziawszy, czasami czytam Ottinger's rules for Variable and Class Naming, który ma pewną dobrą heurystykę, o której należy pamiętać. Jednym z moich ulubionych jest użycie zdań rzeczownikowych, takich jak - person.getName() lub bitTorrentClient.findPeersFromTracker(). W obu tych przypadkach intencja linii kodu brzmi podobnie do frazy w języku angielskim.

+0

+1 - połączenie Ottinger jest dobre. –

+0

"get name" i "find peers from tracker" to wyrażenia czasownikowe :) –

+0

http://agileinaflash.blogspot.com/2009/02/meaningful-names.html to krótka forma moich zasad nazewnictwa. Długa forma to rozdział 2 Clean Code. –

6

Czasami można zmniejszyć długość nazwy funkcji, po prostu zmieniając jej nazwę. Zamiast:

void RetrievePropertiesFromRemoteStore() 

Można użyć:

void RetrieveRemoteProperties() 

zamiast:

bool CheckToSeeIfUserIsAuthorized() 

Zastosowanie:

bool IsUserAuthorized() 

Innym sposobem, aby go zmniejszyć to przemyśleć, co się funkcja działa. Zamiast jednej funkcji takich jak to:

void GetUserProfileAndSetUpSession() 

Można mieć:

void GetUserProfile() 
void SetupSession() 
+5

w przypadku IsUserAuthorized, jeśli jest to metoda w klasie, to user.IsAuthorized() lub service.IsAuthorized (użytkownik) jest jeszcze lepszy. – plinth

1

Heh. Uderzyło mnie, gdy przeczytałem tytuł pytania, że ​​akt programowania można nazwać "kłopotami wymyślania dobrych nazw dla funkcji".

-3

Można używać numeracji i postfixes „_ *”, aby uniknąć zbyt wiele nazw w kodzie:

void DoX() 
void DoX_Decode1()   <-- this name shows that this function is only used by DoX() 
void DoX_Decode2() 
void DoX_Decode3() 
void DoX_Find1() 
void DoX_Find2() 
void DoX_Find3() 

Można również grupa podobną funkcjonalność z prefiksów:

void tcpip_ShowConnectDialog() 
void tcpip_AcceptConnections() 
void logging_WriteToFile() 
void logging_UpdateLogWindow() 

ten sposób można uzyskać unikalne nazwy funkcji (pomaga w wyszukiwaniu i wyszukiwaniu i zamianie) i nadal są stosunkowo krótkie. Unikasz także kłopotów z wyodrębnianiem ich do oddzielnej klasy i oddzielnego pliku kodu. Po prostu trzymajcie przedrostki krótkie, abyście mogli je zignorować i zobaczyć za nimi.

+1

DoX_Decode2 absolutnie nic dla mnie nie znaczy. I, być może, używasz języka nie-OO, ale DoX.find() i DoX.Decode() jest o wiele lepszy IMO. Mówię to, ponieważ mówisz o oddzielaniu klasy ... więc domyślam się, że to OO. Wreszcie, nie należy unikać refaktoryzacji z powodu "kłopotów z ich wydobyciem" .. z dobrym IDE (kaszel * kaszel * zaćmienie *), zmiana nazwy i metoda ekstrakcji jest naprawdę przyjemna. :) – user35978

+0

Tak, jestem naprawdę staroświecki w ten sposób. Nienawidzę mieć oddzielną klasę i plik na każdą małą rzecz. Dla mnie praktycznie niemożliwe jest sprawienie, abyś był krótszy (poprzez refaktoryzację), kiedy wszystko, co widzisz, jest abstrakcją wysokiego poziomu, że wszyscy robią "sence" i "walczą" o swoje istnienie (przepraszam za tak daleko idące analogie). Również bardziej wierzę w listy niż w hierarchie lub drzewa. Na przykład wolałbym raczej używać wielu dokumentów programu Excel z tabelami 2-wymiarowymi, tego jednego dokumentu xml z hierarchiczną strukturą drzewa (jeśli ma to dla ciebie jakiś sens). Dlatego nienawidzę hierarchii klas OO. – AareP

1

Kiedy zabraknie sensownych nazw, po prostu użyj liter alfabetu. Po ich wyczerpaniu wybierz losowe słowa ze słownika.W ten sposób nigdy cię nie zwolnią, bo tylko ty rozumiesz kod.

+0

Hah! Zobacz http://stackoverflow.com/questions/961942/what-is-the-worst-programming-language-you-rever-worked- z przykładami kilku języków, w których prawie tylko pojedyncze litery alfabetu. BASIC Widziałem kiedyś tylko dozwolone nazwy takie jak A i B1 dla liczb całkowitych, a $ D i $ R2 dla ciągów. Ohydny. –

0

Stosując podejście obiektowe, pomaga zmniejszyć ten problem .. connectionsToAccessLines -> connexion.connect (System.getAccessLines());

handleWallVisionSplit -> ten jeden, nie jestem naprawdę pewien, co robi: D Ale, powiedziałbym coś w stylu: wall.handleVision (Wall.split); czy cokolwiek, myślę, że rozumiesz o co mi chodzi.

Czasami, gdy trudno jest nazwać zbyt specyficzną funkcję, może to być spowodowane tym, że kod nie jest wystarczająco wysoki. Na przykład: readSecondWordOfLine (a_line) -> line.split() [1].

Albo, sort (sortWithSecondWordOfLine()) może stać się, sort (line => split (linia) [1]). Wiem, że nie zawsze jest to tak czyste, jak we wszystkich językach, ale rozumiem. W przypadku C++ można na przykład użyć kompozytu bind i stl do zbudowania jednego wyrażenia liniowego zamiast tworzenia nowej metody.

Mogę więc podsumować to, mówiąc: jeśli masz zbyt techniczną metodę - która jest zazwyczaj bardzo krótka, ponieważ w przeciwnym razie łatwo byłoby znaleźć nazwę poprzez abstrakcję funkcjonalności - dobrze jest stworzyć nową funkcję/klasę więcej uogólnione abstrakcyjną nazwą i użyj go bezpośrednio w pierwszej funkcji.

Powiązane problemy