Jak tworzyć dobre nazwy klas, funkcji i zmiennych?

1

Kategoria : Jakość kodu

Ten artykuł jest 2 z 2 części w serii Jak pisać kod dobrej jakości?

Każda klasa, funkcja czy zmienna w naszym kodzie źródłowym ma swoją nazwę. Dobór odpowiednich nazw dla wszystkich tych elementów ma fundamentalne znaczenie dla jakości powstającego kodu. Bardzo często w pośpiechu nadajemy nazwy przypadkowe, które nic nie znaczą. Posługujemy się skrótami myślowymi lub akronimami. Dwa miesiące później, z trudem analizujemy swój własny kod próbując odgadnąć co robi ta funkcja i do czego służy tamta zmienna. Nazwy mają ogromne znaczenie więc czas poświęcony na ich odpowiednie dobranie to bardzo dobra inwestycja.

Na co więc zwrócić szczególną uwagę? Jak konstrułować poprawne nazwy róznych elementów naszego kodu żródłowego? Istnieje kilka prostych zasad, które nam w tym pomogą.

Używaj nazw, które coś znaczą – nazw opisowych

Pamiętaj o tym, że nasz kod nie jest przeznaczony tylko dla kompilatora czy interpretera. Bardzo często, czytają go także ludzie więc nazwy użyte w kodzie, powinny jasno informować jaki jest cel, co robi oraz jak jest używany utworzony przez nas element kodu źródłowego. Nazwa powinna być na tyle opisowa, aby nie wymagała żadnego, dodatkowego komentarza. Jeśli utworzymy zmienną :

int s; //pozostały czas w sekundach

jesteśmy zmuszeni dodać komentarz do kodu. Najlepiej jeszcze, powtórzyć ten komentarz w każdym miejscu, w którym użyjemy zmiennej s. Zamiast tego, możemy zadeklarować zmienną o innej nazwie, np :

int remainingTimeInSeconds;

czyli użyć nazwy, która coś znaczy, nazwy opisowej, co w sposób szczególny przyczyni się do poprawy czytelności tworzonego przez nas kodu.

Powinniśmy oczywiście dążyć do tego, aby nazwy były możliwie jak najkrótsze, ale (poza uzasadnionymi przypadkami) nie róby tego kosztem czytelności.

Nie używaj nazw, które mogą wprowadzić w błąd

Od braku informacji gorsze jest tylko jedno, dezinformacja. Jeśli użyjemy nazwy, która nic nie znaczy, osoba analizująca nasz kod straci mnóswto czasu ustalając co przechowuje zmienna lub co robi funkcja. Jeśli natomiast nazwa będzie coś znaczyć i to znaczenie okaże się fałszywą wskazówką, straci tego czasu dwa razy więcej. Fałszywe wskazówki pojawiają się w naszym kodzie przede wszystkim z dwóch powodów :

- nazwa coś znaczy, ale jest źle dobrana przez autora kodu,

- nazwa coś znaczy, była prawidłowo dobrana przez autora kodu, jednak po niedbałej modyfikacji przez innego programistę, nazwa pozostała a cel, funkcjonalność lub sposób użycia się zmienił.

Dla przykładu, uznano, że nie podajemy już pozostałego czasu w sekundach (nasza zmienna int remainingTimeInSeconds)  tylko w minutach więc zmieniono wartość przechowywaną w tej zmiennej ale nazwę pozostawiono.

Używaj nazw odległych znaczeniowio

Czasem w naszym kodzie źródłowym pojawiają się nazwy elemetów tego samego typu, bardzo zbliżone znaczeniowo. Powiedzmy, że mamy klasę Student. Wszystko jest w należytym porządku, dopóki  w kodzie nie pojawi się druga klasa, tym razem o nazwie StudentInfo, StudentData czy StudentObject.  Której klasy należy teraz użyć, aby dotrzeć do historii wpłat czesnego dla danego studenta?

Starajmy się dbać o to, aby nie tworzyć takich dylematów. Aby nasze nazewnictwo nie tylko coś znaczyło, ale było również jednoznaczne. Inne przykłady, tym razem z nazwami funkcji (metod) :

getActiveStudent
getActiveStudents
getActiveStudentAccount

Takie historie pojawiają się w kodzie dość często i są rozumiane wyłączenie przez swoich autorów – z tym, że przez pierwsze dwa miesiące po ich stworzeniu.

Używaj rzeczowników jako nazw klas

Nazwa klasy powinna być rzeczownikiem lub wyrażeniem rzeczownikowym. Poprawne nazwy klas to np. :

Student
Address
LogParser

Używaj czasowników jako nazw funkcji

Nazwy funkcji (metod), powinny być czasownikami lub wyrażeniami czasownikowymi. Dla przykładu możemy podać :

delete
getName
setName
deleteLogs

Używaj jednego określenia dla podobnych operacji

Należy używać tego samego określenia dla wszystkich podobnych operacji. Np. nazwy metod do pobierania różnych wartości z obiektu powinny być skonstrułowane z użyciem tego samego przedrostka. Jeśli się zdecydujemy na get, czyli np. getName, to do konstrułowania nazw dla innych metod pobierających wartości z obiektu powinniśmy konsekwentnie używać przedrostka get a nie np. fetch, retrive czy list.

Wprowadź normy  i używaj metryk jakościowych

Dobrą praktyką jest wprowadzenie do firmy norm odnośnie tworzenia nazw elementów kodu źródłowego. Takie rozwiązanie funkcjonuje w wielu firmach tworzących oprogramowanie i efekty tego są bardzo widoczne.

Dodatkowym orężem w walce ze złym nazewnictwem są metryki jakościowe kodu. Wdrożenie w firmie narzędzia do generowania takich metryk, np. CheckStyle oraz uzbrojenie go w zestaw odpowienich wyrażeń regularnych pomoże nam na bieżąco kontrolować zgodność tworzonego kodu z większością wprowadzonych w firmie norm dot. nazw elementów kodu źródłowego.

Dzisiejsze środowiska programistyczne np. Eclipse czy NetBeans dają nam narzędzia, dzięki którym operacje takie jak zmiana nazwy, są bardzo proste i bezpieczne. Korzystajmy więc z ich dobrodziejstw. Przyglądajmy się krytycznie nazwom w naszym kodzie źródłowym i zmieniajmy je jeśli trzeba. Stosujmy się przy tym do zbioru powyższych zasad a jakość naszego kodu z pewnością znacznie się poprawi.

Nawigacja serii«Czy jakość kodu ma znaczenie?

Czy jakość kodu ma znaczenie?

1

Kategoria : Jakość kodu

Ten artykuł jest 1 z 2 części w serii Jak pisać kod dobrej jakości?

Jakość koduJaka jest różnica między czystym kodem (ang. clean code) a brudnym (ang. dirty code)? Dlaczego piszemy brudny kod? Czy czysty kod ma w ogóle jakiekolwiek znaczenie?

Niektórzy twierdzą, że jakość kodu nie ma znaczenia, ważne by działał. Nieopatrzenie rozumiejąc metodyki Agile – w pogoni za zwinnością i szybkością – zapominają o dobrych praktykach i standardach. Jest jednak wiele przykładów na to, że budowanie kolosów na glinianych nogach bardzo źle się kończy. Wiele dobrze zapowiadających się firm wypadło z rynku, ponieważ nagle zaczęły mieć kłopoty z jakością. Jak się później okazywało, problemy spowodowane brudnym kodem.

Schemat w każdym przypadku był bardzo podobny. Firma wchodziła na rynek i rozwijała się w piorunującym tempie. Zdobywała klientów, wyprzedzała konkurencję. Jednak po kilku, kilkunastu miesiącach nie była już w stanie z taką dynamiką dokładać kolejnych funkcjonalności. Po następnych kilku miesiącach, wydajność zespołów pracujących w projekcie malała już w zastraszjącym tempie a firma traciła swoich kluczowych klientów, ze względu na pogarszającą się jakość. Kiedy orientowano się w czym rzecz, system trzeba było napisać praktycznie od nowa – kolos stał na glinianych nogach. W tym czasie konkurencja, która dobrze rozłożyła siły w tym biegu z łatwością wygrywała cały wyścig. Okazywało się, że biznes to nie sprint ale bieg długodystansowy.

Każdy z nas zapewne spotkał się z problemem kodu złej jakości. Kiedy trzeba zmodyfikować nieznany nam brudny kod, nasza praca zmienia się w koszmar. Zanim uda nam się ustalić znaczenie zmiennych z1, z2 czy Ol (duże „O” oraz małe „el”) oraz przejrzeć deklaracje i definicje metod o dezinformujących nazwach, to nie mamy już siły na przebrnięcie przez wielokrotnie zagnieżdżone instrukcje if, for a to wszystko jeszcze w pętli while o niespotykanej liczbie warunków. Wypijamy wtedy morze kawy, siedzimy po godzinach i w końcu dajemy radę… Ale jakim kosztem?

Dlaczego tak się dzieje, dlaczego piszemy kod złej jakości?

Moim zdaniem, powody są co najmniej trzy :

  • brak świadomości, że może być inaczej,
  • brak czasu lub doświadczenia potrzebnego na stworzenie czystego kodu,
  • brak wiedzy potrzebnej do tworzenia kodu dobrej jakości .

Fakt, że znalazłeś się na tej stronie drogi Czytelniku, świadczy o tym, że problem pierwszy, czyli brak świadomości, że może być inaczej, już Cię nie dotyczy ;).

Zajmijmy się więc problemem drugim, czyli brakiem czasu lub doświadczenia potrzebnego na stworzenie czystego kodu. Programista, który zna dobre praktyki oraz standardy dot. tworzenia kodu dobrej jakości ale nie ma doświadczenia w ich stosowaniu, potrzebuje więcej czasu, na stworzenie czystego kodu niż na stworzenie kodu działającego, ale niekoniecznie dobrej jakości. Podczas estymacji czasu potrzebnego na wykonanie danego zadania nie odważy się dołożyć 30% tylko po to, aby napisać kod dobrej jakości. Nie zrobi tego z obawy przed niezrozumieniem ze strony innych programistów nie wspominając o przełożonym. Jeśli jednak nie zacznie programować zgodnie ze standardami, nigdy nie nabierze doświadczenia, które pozwoli mu to robić w krótszym czasie. Koło się zamyka. Jedynym rozwiązaniem w takiej sytuacji jest rozmowa z zespołem oraz przełożonym, w której należy uświadomić wszystkich o tym, że problem istnieje i do czego może doprowadzić.

Problem trzeci, czyli brak wiedzy potrzebnej do tworzenia kodu dobrej jakości. Jak wygląda ten czysty kod i czym się charakteryzuje? Jakich technik należy używać, na co zwracać szczególną uwagę aby tworzyć kod dobrej jakości?. Nie uczą tego w szkołach a podręczniki programisty ograniczają się zazwyczaj do podania semantyki i syntaktyki danego języka, spychając zagadnienia związane z jakością kodu na odległy plan.

Każdy kod w zależności od swojego przeznaczenia, będzie optymalizowany pod różnym kątem. Trochę inaczej będzie wyglądał dobrej jakości kod firmware’u do kontrolera RAID a inaczej kod testów jednostkowych. Instnieje jednak zbiór cech, charakterystycznych dla czystego kodu, niezależnie od jego przeznaczenia :

  • Czysty kod powinien zachowywać się przewidywalnie. Kiedy prześledzimy oczami fragment kodu, nie powiniśmy mieć żadnych wątpliwości do czego służy a po jego uruchomieniu powinien zrobić dokładnie to, czego się spodziewaliśmy.
  • Czysty kod powinien być prosty i przyjemny w czytaniu. Jego analiza nie powinna być skomplikowana. Czytając go, powinieneś mieć wrażenie, że opowiada zaimplamantowaną historię.
  • Czysty kod powinien mieć objętość oraz wydajność zbliżoną do optymalnej. Zamniejszamy objętość oraz poprawiamy wydajnośc do momentu, kiedy nie robimy tego kosztem czytelności.
  • Czysty kod powinien być pokryty testami jednostkowymi i akceptacyjnymi, które przechodzą z wynikiem pozytywnym. Praca z kodem pokrytym testami jest o wiele bardziej komfortowa. Każdą zmianę w kodzie możemy od razu przetestować na okoliczność złego oddziaływania na resztę kodu i to zarówno na poziomie jednostkowym jak i akceptacyjnym.

Aby sprostać powyższym założeniom, musimy zwrócić uwagę na każdy element składowy kodu, czyli zadbać o :

Każde z tych zagadnień postaram się opisać w osobnym artykule.

Nie będzie w tym żadnej przesady, jeśli na pytanie zawarte we wstępie, „jaka jest różnica między czystym kodem a brudnym?” odpowiemy, że dokładnie taka sama jak między „być albo nie być”. Firmy, które poważnie traktują swoją przyszłość – dbają o jakość kodu. Robią to poprzez wprowadzanie odpowiednich standardów kodowania, programy szkoleniowe oraz stosowanie metryk jakościowych kodu. Jeśli w Twojej firmie z jakiegoś powodu o tym wszystkim zapomniano, to może jest to ostatni moment, na wprowadzenie zmian.

Nawigacja seriiJak tworzyć dobre nazwy klas, funkcji i zmiennych?»