Niekoniecznie długie nazwy

2011-10-09 23:22

Porzekadło głosi, że w informatyce są tylko dwa trudne problemy: nazewnictwo, mechanizmy cache‘owania i pomyłki o jedynkę. Jeśli chodzi o jeden dwa ostatnie, to może przyjrzymy się im przy innej okazji… Dzisiaj chciałbym za to zająć się pierwszym z nich: dobieraniem odpowiednich nazw dla konstrukcji programistycznych, takich jak funkcje czy klasy.

Nie każda nazwa jest właściwa. O tej trywialnej prawdzie każdy pewnie przekonał się już dawno, zwłaszcza jeśli przechodził przez fazę zmiennych a, b, c lub funkcji fun1 i fun2. Zdaje się zresztą, że kiedyś była to powszechna przypadłość, co widać zwłaszcza w przypadku starych API *niksowych. Najwyraźniej jednak poszliśmy kolektywnie po rozum do głowy i dziś już nikt nie nazwie funkcji wait3 czy wait4.

Nietrudno jest oczywiście wskazać podstawowy problem tego rodzaju nazw. Jakkolwiek jest on ściśle związany z długością, nie uzasadnia to automatycznie stwierdzenia, że wszystkie krótkie nazwy są złe. Żeby nie odchodzić daleko, wystarczy tylko spojrzeć na POSIX-owe, uniwersalne funkcje read i write. Ich nazwom nie brakuje dokładnie niczego; przeciwnie, próba dodania czegoś więcej wprowadzałaby tylko zamieszanie. readFromFileDescriptor może i wskazywałaby wyraźnie na źródło danych, ale czy zupełnie poprawne użycie takiej funkcji na uchwycie sieciowego gniazda (socket) nie byłoby mylące? O jakim pliku wtedy mówimy?
Naturalnie, w *niksach “wszystko jest plikiem” i należy o tym wiedzieć. Lecz skoro tak jest, to co zyskujemy przez dłuższą nazwę funkcji read? Niby z czego innego niż z pliku mielibyśmy czytać?…

Dywagując na ten temat muszę koniecznie zaznaczyć, że nazwy zaśmiecone oczywistymi informacjami nie są wcale hipotetycznym problemem. Moim ulubionym przykładem – ze względu na swoją groteskową wręcz ekstremalność – jest poniższe wywołanie:

  1. NSString* someString = @"Ala ma kota";
  2. NSString* otherString = [someString
  3.                          stringByReplacingOccurrencesOfString:@"kota"
  4.                          withString:@"psa"];

Ja wcale nie żartuję – tak w Objective-C (OSX/iOS) wygląda zastępowanie jednego ciągu w tekście innym. Zawsze chętnie wysłucham argumentów przekonujących o ekspresywności i opisowości podobnych nazw, ale nigdy nie uwierzę, że koderzy je rzeczywiście czytają. Zgaduję, że ich percepcja u statystycznego programisty polega na dostrzeżeniu “Repl” lewym okiem i “ccurr” prawym – albo coś w tym rodzaju. Jeśli mam rację, to nazwa ta jest znacząca w zaledwie 22 procentach; trudno to uznać za dobry stosunek sygnału do szumu.

Czy można było zrobić to lepiej? Zapewne – weźmy chociażby Javę:

  1. String someString = "Ala ma kota";
  2. String otherString = someString.replaceAll("kota", "psa");

Wygląda to całkiem dobrze. Okazuje się, że można użyć trzy razy krótszej nazwy i osiągnąć niemalże ten sam efekt, posługując się po prostu samą składnią języka (kolejnością parametrów i wartością zwracaną) zamiast długich tekstowych opisów.

Rozwlekłe nazwy – nawet jeśli camelCase czyni je znośnymi – nie zawsze są więc dobrą odpowiedzią. Czasami mogą one być równie nadmiarowe co niepotrzebne komentarze.

Tags: , , ,
Author: Xion, posted under Programming »


6 comments for post “Niekoniecznie długie nazwy”.
  1. higrys:
    October 9th, 2011 o 23:53

    Karolu, właśnie Twój ostatni przykład dość dobitnie pokazuje że krótkie nazwy mogą być złe. W tym przypadku zadziała ok, ale
    jeśli spojrzysz na API javowe, to String.replaceAll działa zupełnie inaczej niż można by się było spodziewać z nazwy. Bo zastępuje ona WYRAŻENIE REGULARNE a nie string (w przeciwieństwie do podobnej metody String.replace która zastępuje stringi właśnie)…

    Oczywiście gorzej to świadczy o niespójności API Javy a nie “złych krótkich nazwach” ale czyż nie lepiej do czytania kodu wyglądało by:

    1. String otherString = someString.replaceAllStrings("kota", "psa");
    2. String yetAnotherString = someString.replaceAllRegexps("[ko]*ta", "psa");
  2. Daniel:
    October 10th, 2011 o 0:03

    Ja na codzień mam do czynienia z takimi programami jak SPSMakro80 albo UP2. Główne programy nazywamy Folge1.
    Jeśli chcesz ustawić sobie jakąś zmienną proszę bardzo, np F123.

  3. SebaS86:
    October 10th, 2011 o 0:15

    Xion, bardzo dobry przykład. :) Jednak używanie takich nazw jest konsekwencją przyjętej konwencji i skutków ubocznych niektórych właściwości języka. Niestety Obj-C ma jedną zasadniczą wadę, a jest nią “słabsza” silna typizacja (porównując np. do Java’y) i bardzo ciężkie do wychwycenia błędy podczas dynamicznej analizy w przypadku nawet drobnej pomyłki. W skrócie łatwiej usunąć błąd czytając kod źródłowy niż gapiąc się w treść rzuconego wyjątku po wywołaniu selektora na obiekcie, który nie potrafi go obsłużyć. Dodatkowo w Obj-C nie ma przeciążania… więc mamy całą rodzinkę różnych metod do obsługi różnych obiektów i jakoś te metody trzeba nazwać. Replace1All … ReplaceNAll nie wydają się tutaj najlepszym wyborem. :)

    Nie mam żadnych statystyk na to ale wydaje mi się, że dłuższy wyraz ciężej niechcący pominąć, i przy okazji zmusza to trochę programistów do dzielenia dłuższych wyrażeń na pojedyncze linię – po prostu nie da się tego w pewnym momencie czytać. ;D

    Wyżywając się na Obj-C, jeszcze fajniejszym a dość często używanym przykładem jest UIAlertView. Ale generalnie jakoś właśnie chyba przez to lubię ten język. Mimo wszystko jest na swój sposób ekspresywny.

  4. agent_J:
    October 10th, 2011 o 14:16

    W przypadku przykładu Obj-C wszystko ładnie widać. W przykładzie Javy co zastępuje co ? Kot psa czy pies kota ?

  5. vashpan:
    October 10th, 2011 o 21:55

    Heh, no tak, Obj-C “slynie” z tego typu nazw. Jak dluzej sie siedzi w tym jezyku, ma to wiecej sensu. Po pierwsze – tego typu nazwy metod sa tak naprawde nazwami metod z nazwanymi parametrami – przy czym kazdy parametr musi byc obligatoryjnie nazwany ( w sumie to nie do konca, ale pominmy to ;) ). Rozwleka to oczywiscie strasznie kod, ale piszac w stylu jaki podales, czyli przy dlugich metodach, kazdy parametr w osobnej linijce – staja sie to IMO nawet bardziej czytelne niz w stylu klasycznego C. Rzadziej tez trzeba zagladac do dokumentacji.

    Po czasie czlowiek sie “wprowadza” w taki styl i sie okazuje ze samemu zaczyna tworzyc takie rzeczy ;0

  6. pieczara:
    October 11th, 2011 o 9:39

    Wymyślając nazwy metod sam mam tendencję do tworzenia długich i opisowych ;)

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.