We wpisie na temat czystego kodu jako jeden z jego atrybutów wymieniłem nadawanie odpowiednich nazw.

 

Napisany kod jest czytany jest przez kompilator. Dla niego nie ma znaczenia to jak obiekty, zmienne czy inne rzeczy będą nazwane. Ostatecznie będzie kod maszynowy, który się wykona albo nie. Jednakże najczęściej to kod ten czytany jest albo przez autora albo też innych programistów.

 

Z uwagi na to, że będzie to czytała istota ludzka to warto by było aby czytający mógł się skupić na tym co ten kod robi a nie jak wygląda. Jak piszesz kod dla kolegi, to pisz go tak jak ty byś chciał aby on pisał dla Ciebie.

 

Konwencja nazewnicza

Programujesz od dłuższego czasu? Zmieniasz projekt? Siadasz do środowiska, w którym programujesz. I co? Piszesz jak zawsze czy tak jak inni w projekcie? Konwencja nazewnicza używana dotychczas może nie być taka sama jak w nowym projekcie. Jeżeli uważasz, że to w jaki sposób zespół nazywa elementy w swoim kodzie jest daleki od idealnego, to zmieńcie tą praktykę wspólnie. Jednakże, niech będzie spójność.

 

Inspekcja kodu

Jeżeli w projekcie nad którym pracujesz przeprowadzasz regularnie inspekcję kodu, to konwencja nazewnicza ma ogromne znaczenie. Sprawdzając kod innej osoby zamiast skupiać się na kłujących w oczy nazwach lepiej poświęcić uwagę na to co ten kod rzeczywiście robi. Albo powinien robić.

 

Sposób komunikacji

Pisanie kodu to nie tylko komunikacja z kompilatorem. Pisząc kod komunikujesz się z innymi osobami, które będą go w przyszłości czytały. Po pierwsze niech napisany kod jasno wyraża cel. Po drugie niech łatwo się go czyta. Jak już te warunki masz spełnione to pomyśl o tym jak będą Ciebie oceniać inni. Napisany przez Ciebie kod jest Twoją wizytówką. To jak Twoje CV. Tak więc dbaj o to by wyglądał on jak najlepiej.

 

Powszechne nazwy to część języka programowania

Już wcześniej cytowałem Phila Karltona.

There are only two hard things in Computer Science: cache invalidation and naming things.

 

Problem nie musi być jednakże tak duży jak by się mogło wydawać. Zacznij od tego by nazwy określające powszechne zagadnienia stały się częścią języka programowania. Nie wymyślaj nowych nazw na istniejące już terminy. Na to nie sensu tracić czasu. Odstaw swoje ego a kreatywność wykorzystaj na lepsze rozwiązanie problemów z jakimi się mierzysz. Na pewno nimi nie są nazwy jakich powinieneś używać.

 

Bądź też konsekwentny w tym co robisz. Jak spełnisz ten warunek to nazywanie elementów kodu przestanie być problemem. Stanie się to tak naturalne jak pisanie nowej klasy czy deklarowanie zmiennej.

 

Nazwy łatwe do wymówienia

Jeżeli musisz prezentować co robi Twój kod innym osobom z zespołu, to niech on będzie napisany tak by łatwo było Ci go wymówić. Nie komplikuj w tym miejscu. Nie skracaj przesadnie nazw. Nie ma sensu łamać sobie języka omawiając kod tylko po to by zaoszczędzić kilka znaków napisanych na klawiaturze.

 

Nazwa wskazuje cel

Nazwa metody, argumentów, zmiennych itp. Powinny jasno wskazywać na cel w jakim będą użyte. Jeżeli warunek ten zostanie spełniony to kod staje się samo komentujący. Analizując tak napisany kod nie trzeba poświęcać zbyt wiele czasu na rozszyfrowanie działania algorytmu. Zagadnienie to nawiązuje na używania powszechnych nazw. W przypadku zmiennych może być to bardzo proste, jednakże większy poziom skomplikowania jest w przypadku metod. Metody jest trudniej nazywać szczególnie w przypadku gdy robią zbyt dużo rzeczy. Na ratunek przychodzi pojedyncza odpowiedzialność. Temu zagadnieniu poświęcę osobny wpis. Pisanie kodu SOLID-nego to bardzo ciekawy, choć trudny aspekt programowania. Pozornie trudny, bo gdy nawyki się już wyrobi to trudne stają się inne rzeczy.

 

Komentarze w kodzie

Jest to temat bardzo często kontrowersyjny. Ja jednakże wychodzę z założenia, że kod sam się powinien komentować. Jak wszystko zostanie dobrze nazwane to nie ma potrzeby dodawania komentarzy. Po co spędzać czas na pisanie komentarzy jak można go wykorzystać na wymyślenie dobrej nazwy. Komentarze w kodzie to bardziej złożony temat. Czasem straszny a czasem zabawny. Poświęcę na niego osobny wpis w przyszłości.

 

Długość nazw

Nazwy powinny być na tyle długie by było wiadomo jaki jest cel tego na co wskazują. Jednakże powinny być też na tyle krótkie, by nie trzeba było używać suwaka poziomego lub zmniejszania wielkości czcionki aby wszystko objąć wzrokiem. PO prostu ich długość powinna być w sam raz. Jeżeli nazwa jest zbyt długa to może to oznaczać na złamanie zasady pojedynczej odpowiedzialności. Znowu kłania nam się jeden z filarów SOLID-nego kodu. Reasumując nazwa powinna być zwięzła ale nie taka która ma w sobie ukrytych wiele skrótów. Najlepiej jak skrótów w nazwach nie ma w ogóle.

 

Jeżeli akcja to czasownik

Metody odpowiedzialne są za jakieś akcje. Dlatego też w ich nazwie powinien znajdować się czasownik, lub też powinny być czasownikiem. Warto spojrzeć na ten problem z perspektywy kontekstu w jakim jest kod wykonywany. W przypadku metod oczekujemy, że coś zrobią. Jeżeli funkcja ma pełni rolę gettera, np. zwracającego wartość CSV obiektu, to może być nazwana GetCSV. Obiekt, mógłby mieć także właściwość CSV, której getter by zwracał tą samą wartość. Jednakże metoda sugeruje, że coś się będzie wykonywać, natomiast właściwość, że wartość jest już zapisana w obiekcie. Może mieć to wpływ na wydajność programu.

 

Ciekawym praktycznym przykładem, z którym większość programistów .NET ma styczność na co dzień są metoda i właściwość Count w LINQ. W tym przypadku nazwa może być zarówno rzeczownikiem jak i czasownikiem. Jednakże wykorzystanie właściwości i metody może mieć określony wpływ na wydajność. W przypadku gdy zwracany obiekt jest typu ICollection, wtedy metoda odwołuje się bezpośrednio do właściwości Count, która została już obliczona podczas dodawania i usuwania elementów. Natomiast w przypadku gdy obiekt nie jest typu ICollection, to wtedy cała kolekcja musi być enumerowana aby obliczyć ilość elementów.

 

W przypadku oporu przed czasownikami dobrze jest chociaż zastosować przyimek lub zaimek, który będzie wskazywał na relację pomiędzy funkcją i jej wynikiem. Przykładem takiego podejścia jest rzutowania typów. Np.. ToString lub IndexOf.

 

Brak akcji jest rzeczownikiem

W przeciwieństwie do metod, od zmiennych i właściwości oczekujemy, że będą one statyczne. Tutaj nie ma z reguły żadnej akcji. Pewnym wyjątkiem są właściwości, które jako minimum wykonują akcję ustawienia wartości ukrywającej się pod nim zmiennej. Z racji tego, że nazywają one coś statycznego powinny być rzeczownikami.

 

Jedna czynność = jedna nazwa

Unikaj używania wielu nazw do określenia tej samej czynności. Jeżeli jest kilka klas, które mają operować na źródle danych to niech metody odpowiedzialne za poszczególne akcje nazywają się tak samo. Czyli jak coś ma być zapisane to metoda w każdej klasie niech nazywa się Save, a nie w jednej Save, w innej Persist a jeszcze w innej Record. Tutaj powrócę do powszechności nazw. Jeżeli jedna nazwa jest używana do opisania danej akcji i jest to traktowane jako część języka to odpada konieczność silenia się nad tworzeniem nazw. Po prostu ta konkretna akcja staję się częścią języka.

 

Tak samo, nie powinno się używać jednej nazwy do nazwania wielu różnych akcji. Załóżmy, że klasa może pobierać wartości z różnych źródeł danych. Np. z bazy danych i pliku. Użycie w tym przypadku nazwy Get dla obu operacji wyciągania danych utrudniłoby czytanie kodu. O wiele czytelniejszy byłby kod gdyby nazwy metod były GetFromDatabase  oraz GetFromFile. Dalej metody, mogłyby przyjmować różną ilość, bądź tym parametrów wejściowych, jednakże byłoby jednoznaczne z jakiego źródła pobierane są dane. To takie uproszczenie tylko, gdyż w przypadku tego typu problemu, lepiej było by zastosować wzorzec Repository. Wtedy rzeczywiście nazwa mogłaby być identyczna, ale to już nazwa klasy wskazywałaby na typ źródła danych.

 

Nieczytelny kod pokusą do jego przepisania

Kod, który jest nieczytelny i trudny do odszyfrowania staje się pokusą do jego przepisania. Przecież jak się przepisze kod na taki, który będzie bardziej czytelny to łatwej będzie go utrzymywać. Tak może i często jest. Jednakże, każda próba przepisania, wymyślenia na nowo, programu zwiększa ryzyko wprowadzenia błędów lub co więcej niepożądanej zmiany logiki istniejącego programu.

 

Najlepiej aby pisać kod, by był on zrozumiały dla innych osób i nie rodził pokus przepisywania. Prosta zmiana nazwy także może rodzić problemy w przypadku, gdy ktoś używa dynamicznych typów danych. Niestety ale na etapie kompilacji nie będzie wiadomo czy stare nazwy są dalej w użyciu.

 

To kilka zasad, których ja staram się przestrzegać pisząc kod z definicji czytelny. Jednakże to jest tylko mój styl i każdy może kodować w inny sposób. Masz inne spostrzeżenia, proszę podziel się opinią.