
Clean code
Możliwe, że zdarzyło Ci się czytać kod innego programisty – czy to na jakimś forum, a może kod kolegi. Czy czytanie cudzego kodu jest łatwe?
A no nie zawsze, szczególnie wtedy nie jest łatwe, gdy drugi programista nie korzysta przynajmniej z podstawowych założeń Clean Code.
Sami musimy się wcielić w tego drugiego programistę, która piszę kod nie tylko dla siebie – ale też dla innych.
Postaram Ci się pokazać kilka koncepcji, które pozwolą Ci tworzyć tak kod, tak jak byś miał go rozwijać/utrzymywać przez całe swoje życie – do dzieła!
Komentowanie kodu
Co do komentarzy jest jedna prosta zasada – komentarzy prawie nie powinno być w kodzie – takiej zasady powinniśmy się trzymać. Jedynym wyjątkiem są tzw. Java Docsy – czyli komentarze na podstawie, których jest generowana dokumentacja.
Skoro nie możemy korzystać zbyt często z komentarzy to musimy zadbać o jedną rzecz – pisać kod samotłumaczący się!
Jeżeli sam kod od samego początku nic o sobie nie mówi to jest bardzo źle – jednak nie ma co teraz panikować, wystarczy zastosować kilka prostych zasad.
Nazwy zmiennych
Wszystkie zmienne nazywaj tak, aby na pierwszy rzut oka było wiadomo co w niej jest przechowywane – w jakim celu ona tu po prostu jest.
Nie używajmy żadnych skrótowców typu: a1, x, asd, dupa – no chyba, że faktycznie przechowujemy tam obiekt odnoszący się do części ciała.
Przykładowe nazwy, które od razu mówią z czym mamy do czynienia:
int age; String login; Long userId; String url;
Zauważ, że zmienna userId – jest zapisana w notacji lowerCamelCase – jest to najczęściej stosowana konwencja zapisywania nazw zmiennych w Javie.
Skoro nawiązałem już do notacji – wybierz jedną notację, w której będzie pisać całą aplikację – namawiam, aby to była notacja CamelCase.
Zwróć uwagę, że wszystkie nazwy zmiennych są w języku angielskim – zawsze pisz wszystkie nazwy w języku angielskim – nigdy nie wiadomo, kto zajrzy (lub kto będzie chciał zajrzeć) do Twojego kodu.
Metody
Powiedzieliśmy już sobie o zmiennych – czas na metody – również o ich nazywaniu. Wiele konwencji się powtórzy.
Stosuj tą samą notację do nazywania metod jakiej używasz do nazywania zmiennych – w moim przypadku (i większości) jest to notacja lowerCamelCase.
Nazwy metod powinny być w języku angielskim.
Nazwa metody powinna zawierać w sobie bezokolicznik informujący o tym za co jest odpowiedzialna.
Z pewnością lepszą nazwą będzie:
public float calculateAverage(int [] numbers){ };
Niż
public float average(int [] numbers){ };
W drugim przykładzie nie do końca od razu wiadomo co z tą średnią.
Wszystkie metody zwracające powinny zawierać przedrostek – get np.:
public User getUserById(Long id){ };
Tzw. settery powinny zaczynać się od przedrosta – set np.:
public void setUserId(Long id){ };
Zmienne, które zwracają boolean powinny się zaczynać od przedrostów – has i is np:
public boolean isMale(){ }
Lub
public boolean hasCapacity(){ }
Pamiętaj, żeby tworzyć metody, które są odpowiedzialne tylko za jedną rzecz – nie twórz hiper-ekstra dużych funkcji – są one po prostu nieczytelne. Rozbij lepiej swój kod na kilka funkcji i je wywołuj w funkcji odpowiedzialnej za daną funkcjonalność.
Zamiast tworzyć taką funkcję:
public void registerUser(User user){ if(userDao.existsUserByLogin(user.getLogin()) && userDao.existsUserByEmail(user.getEmail())){ userDao.addUser(user); } }
Lepiej rozbić to na kilka funkcji:
public boolean isNotLoginExist(String login){ return userDao.existsUserByLogin(login); } public boolean isNotEmailExist(String email){ return userDao.existsUserByEmail(email); } public boolean canRegisterUser(User user){ return isNotEmailExist(user.getEmail()) && isNotLoginExist(user.getLogin()); } public void registerUser(User user){ if(canRegisterUser(user)){ userDao.addUser(user); } }
Na pierwszy rzut oka wiem co gdzie jest sprawdzane – dodatkowo wszystkie te metody mogę używać w innych fragmentach aplikacji!
Klasy
Rozpocznijmy ponownie od konwencji – w przypadku klas stosuję (i zazwyczaj się stosuję) notację UpperCamelCase – czyli nazwa klasy zaczyna się z dużej litery.
Przykładowa klasa:
public class UserService { }
Oczywiście nazwy klas powinny być również zapisywane w języku angielskim – nic się tutaj nie zmienia!
Nazwa powinna już być jednym rzeczownikiem – lub złączeniem kilku.
Na przykłada taka klasa:
public class UserManager { }
Może zawierać w sobie metody odpowiedzialne za zarządzanie użytkownikami – wiadomo o tym od razu, gdy tylko zobaczymy słowo user i manager.
Kolejną klasą może być:
public class UserValidation { }
Od razu wiadomo, że klasa jest odpowiedzialna za wszelką walidację usera.
Kolejnym ważnym zagadnieniem, o którym trzeba pamiętać podczas tworzenia klasy jest zasada jednej odpowiedzialności – o co w niej chodzi?
Chodzi o to, aby klasa była odpowiedzialna tylko za konkretne działania, które można w jakikolwiek skategoryzować.
Zamiast tworzyć klasę klasę UserService – gdzie będą wszystkie metody odpowiedzialne za działania na userach to jest bez sensu – podzielmy to.
Zróbmy osobną klasę odpowiedzialną za komunikację z bazą danych np. UserDao.
Zróbmy klasę odpowiedzialną za walidację użytkowników np. UserValidation.
Nie twórzmy wielkich klas odpowiedzialnych za wszystko – starajmy się, aby nasze klasy były najbardziej możliwe małe i nie brały na siebie zbyt dużej odpowiedzialności.
Podsumowanie
Przedstawiłem Ci kilka zasad, większość z nich możesz od razu wprowadzić w swoje programistyczne życie – mogę Cię zapewnić, że sam sobie kiedyś podziękujesz, gdy zajrzysz w przyszłości do starego kodu. Inni programiści też Ci za to podziękują – może nie osobiście, ale chociaż w duchu.
Na koniec przygotowałem dla Ciebie krótką listę koncepcji, o których wspomniałem w tym artykule:
- Do nazywania zmiennych, metod i klas używaj języka angielskiego!
- Nazwa zmiennej powinna od razu mówić w jakim celu została stworzona.
- Nazwa metody powinna mówić o tym za co jest odpowiedzialna – stosuj bezokoliczniki.
- Nazwa klasy powinna mówić za co jest odpowiedzialna – stosuj rzeczowniki.
- Nie buduj hiper-ekstra-wielkich i skomplikowanych funkcji – pamiętaj, aby dzielić większe metody na mniejsze – kod będzie czytelniejsze, a dodatkowe metody mogą się jeszcze przydać.
- W obrębie całej aplikacji stosuj jedną notację nazewnictwa – w Javie stosuję się lowerCamelCase dla zmiennych i metod oraz UpperCamelCase dla klas.
- Nazwy stałych zapisuj wielkimi literami oddzielając jej człony podkreśleniem (podłogą).
- Nie pisz komentarzy – pisz czysty kod!
A czy Ty stosujesz już te wszystkie zasady w swoim kodzie? O której może nie wiedziałeś, a może jest jakaś zasada, którą stosujesz i chciałbyś się nią z nami podzielić? Czekam na Wasze zasady kodowe w komentarzach, cześć! 😉
super porady dla początkujących 😉
Dzięki wielkie! 😉 Masz może jakieś rady od siebie, które pozwolą pisać czysty kod?
Jestem we wstępnej fazie nauki więc mój los do czystych nie należy. Więc nie wypada mi udzielać rad 😉
To od początku polecam Ci wdrażać koncepcję czystego kodu, aż wejdzie Ci to w krew. 😉
Już żałuję że tego nie robiłem bo aktualnie mój kod “śmierdzi” 😉
Moim zdaniem najważniejsze jest aby kod był możliwy do przeczytania jak książka. Żeby był dobrze opowiedzianą historią. Czytając linia po linii, dowiadujemy się czegoś nt. kolejnych wątków w ‘fabule” 🙂
To prawda, super jest, gdy otwieramy cudzy kod i nie musimy zastanawiać się nad żadnym ifem lub pętlą – wszystko opisują nazwy zmiennych, a jeszcze lepiej pomniejsze funkcje. 😉