Charles Simonyi stworzył dawno temu (w skali czasu istnienia C/C++) pewne standardy odnośnie nazewnictwa zmiennych i funkcji - zwane notacją węgierską. Tak, tą samą notacją, na którą narzekają tysiące programistów, mających do czynienia z WinAPI czy innymi wynalazkami Microsoftu. Co ciekawe - akurat w WinAPI wspomniana notacja jest używana niepoprawnie. Istnieje możliwość takiego wykorzystania przedrostków, żeby nie przyprawiały o ból głowy - również na innych platformach.
Po co w ogóle notacja węgierska? Porównajmy następujące zapisy:
int width
int pcWidth
int a_pcWidth
Z pierwszego wynika, że zmienna przechowuje szerokość. Z drugiego - że zmienna przechowuje szerokość wyrażoną w jednostkach "pc" (tu: procenty). Z trzeciego - że zmienna jest argumentem, przechowującym szerokość wyrażoną w jednostkach "pc". Ilość znaków różni się niewiele - różnica przekazu jest znaczna. Podobnie z nazwami funkcji:
int to_pixels(int width);
int pc_to_pixels(int width);
int pc_to_px(int pcWidth);
int px_from_pc(int pcWidth)
Co ciekawe, wyłącznie ostatni zapis jest w pełni zgodny z oryginalną NW. Podstawowa zasada dla nazw funkcji i metod: jeśli format czy jednostka wartości zwracanej nie wynika jasno z typu, należy podać ją jako pierwszą część nazwy funkcji. Co ciekawe, w formie suffiksowej ta zasada występuje często na różnych platformach (np. suffix C w nazwie funkcji/metody w Symbianie informuje, że zwrócony obiekt umieszczony jest na CleanupStacku i musi być z niego usunięty przez wołającego, suffiksy A oraz W w WinAPI rozróżniają wersje funkcji używające łańcuchów 16-bit i 8-bit), gdzie nie budzi żadnych obiekcji.
Moja propozycja jest taka, aby wszędzie, gdzie tylko to konieczne, notacja węgierska była używana. Prefiksy są różne, jednolity standard w zasadzie nie istnieje. Każdy programista używający NW prędzej czy później zbuduje sobie własną listę używanych prefiksów. Jeśli komuś się nie chce/nie ma pomysłu, poniżej moja (wstępna) lista.
- px - piksele
- pc - procenty
- pt - partial, przy liczbach zmiennoprzecinkowych oznacza zakres [0; 1]
- cb - ilość bajtów
- cch - ilość znaków
- cv - ilość wartości, odpowiednik ilości znaków przy tablicach innych niż znakowe (rozmiar tablicy)
- w/ws - world space
- c/cs - camera space
- s/ss - screen space
- o/os - object space
- t/ts - tangent space
- an - angle
- n - numer (również: stały indeks)
- ix - indeks (np. w tablicy, wektorze)
- h - uchwyt
- p - wskaźnik, za który kod obsługujący tą zmienną jest odpowiedzialny (musi przekazać lub zwolnić wskazywaną pamięć)
- lp - "daleki wskaźnik", wskaźnik, za który nie bierzemy odpowiedzialności
- fn - funktor, wskaźnik do funkcji, wszystko, co da się wywołać
- m_/m/i - member, internal - pole niestatyczne klasy (z założenia i jest dostępne wyłącznie dla implementacji metod, jego wartość nie jest w żaden pośredni ani bezpośredni sposób dostępna z zewnątrz, służy np. do przechowywania tymczasowego stanu pomiędzy wywołaniami asynchronicznymi)
- a - argument funkcji
- ao_/aout_/out - argument wyjściowy, nie jest w funkcji odczytywany, wyłącznie zapisywany
- ar_/aref_/ref - argument-referencja, może być odczytany i zapisany
- t - thread-insecure, oznaczenie zmiennej, która może być przyczyną problemów w synchronizacji międzywątkowej
- tm/-M - thread-mutex, oznacza albo zmienną-muteks, albo fakt, że funkcja korzysta z muteksu do synchronizacji/upewnienia się o jednolitości danych
- x/-X - cross-thread, zmienna używana w wielu wątkach lub funkcja odwołująca się do pracujących wątków (zwykle oznacza zmienną volatile)
- v - variable, częste oznaczenie pól mutable, zmiennych bardzo często zmieniających wartość, zmiennych oznaczonych volatile celem uniknięcia ewentualnych problemów
- -C - create, wartość zwracana jest nową wartością, wywołujący ma obowiązek ją zwolnić lub przekazać dalej do zwolnienia, używane w nazwach funkcji/metod
- -D - destroy, przekazana wartość (albo this) jest niszczony, używane tylko przy funkcjach/metodach
- k - stała
Oczywiście lista nie jest kompletna (ba, daleko jej do bycia kompletną), niemniej jednak pokrywa zdecydowaną większość nie-zawsze-jasnych sytuacji w moim kodzie. Inspirowane oryginalną notacją węgierską, WinAPI, API Symbiana oraz kilkoma innymi sposobami zapisu. Dodam jeszcze, że ogólna zasada budowania nazwy z wykorzystaniem powyższych modyfikatorów to: [zakres i odpowiedzialność za ewentualne zniszczenie]-[modyfikatory stanu: wątki, const, mutable]-[typ/jednostka wartości]-nazwa-[sufiksy]. I, co ważniejsze - używać tylko tych modyfikatorów, które są sensowne (nie ma np. sensu zapis tmMutex - samo mutex jest wystarczająco jasne ;-) ).
Brak komentarzy:
Prześlij komentarz