7 marca 2025 (updated: 7 marca 2025)

Nazywanie 101: Przewodnik programisty po tym, jak nazywać rzeczy

Chapters

      Udowodniono, że spędzamy więcej czasu na czytaniu kodu niż na jego pisaniu, więc możesz być pewien, że dobre nazewnictwo się opłaci w przyszłości.

      Jednym z najczęstszych problemów programistów jest nazewnictwo. Nie potrafię zliczyć, ile godzin spędziłem na myśleniu, jak nazwać rzeczy i ile godzin zajęło mi zrozumienie kodu zawierającego złe nazwy. Nie ma znaczenia, czy był to obiekt, metoda, klasa czy cokolwiek innego. Udowodniono, że spędzamy więcej czasu na czytaniu kodu niż na jego pisaniu, więc dobre nazewnictwo zawsze się opłaca w przyszłości.

      Używanie dobrych nazw sprawia, że twój kod jest lepszy i czytelniejszy. Pomaga to intuicyjnie zidentyfikować, jakie są odpowiedzialności każdej części kodu. Ułatwia to innym programistom, a także tobie, łatwe czytanie twojej aplikacji w przyszłości.

      W ciągu następnych kilku minut chciałbym wyjaśnić znaczenie dobrego nazewnictwa i podzielić się kilkoma przydatnymi wskazówkami dotyczącymi znajdowania dobrych nazw.

      Poziom Abstrakcji

      Metody i zmienne powinny być nazywane zgodnie z ich znaczeniem. Zanim nadamy nazwę, zastanówmy się, jaka jest odpowiedzialność tego fragmentu kodu.

      Rozważmy przypadek metody, która zwraca ciąg znaków z odległością między Warszawą a Paryżem.

      To proste i wydaje się działać poprawnie, ale co jeśli nieco zmienimy wymagania? Teraz chcę mieć możliwość wyświetlenia zdania na dwa różne sposoby: w kilometrach i milach. Aby to zrobić, muszę wprowadzić zmienną do klasy. Ta zmienna będzie używana do zastąpienia słowa km w metodzie to_s.

      Nowa zmienna powinna być nazwana na jednym poziomie abstrakcji wyżej niż jej wartości. Oznacza to, że musimy najpierw pomyśleć o celu zmiennej. To pomoże nam nadać jej bardziej ogólną nazwę, która nie powinna być zbyt niejasna. Podsumowując ten punkt, nazwa musi sugerować cel zmiennej, ale nie jej możliwe wartości.

      Jakie zatem jest zadanie naszej nowej zmiennej? Ma ona wprowadzić słowa km lub mi do obiektu. Więc nazwa mogłaby brzmieć: kilometry_lub_mile, ale to dokładnie ten sam poziom abstrakcji, co jej wartości. Jeśli chcielibyśmy dodać możliwość użycia innej jednostki (na przykład dni), nazwa kilometry_lub_mile byłaby błędna. Powinniśmy rozważyć coś bardziej ogólnego. Kilometry i mile to jednostki miary, więc dobrą nazwą byłoby jednostka. Jest to na jednym poziomie abstrakcji wyżej (bardziej ogólne) niż odpowiedzialność zmiennej. Dlatego nowa implementacja klasy wygląda jak poniżej:

      Drugą kwestią jest to, że odległość między Warszawą a Paryżem wynosi rzeczywiście 1591 kilometrów, ale to także 988 mil. Czas więc na implementację metody zwracającej odpowiednią wartość. Zasada jest taka sama jak w przypadku zmiennej jednostka. Pomyślmy najpierw o znaczeniu. Nowa metoda ma zwracać wartości 1591 lub 988 reprezentujące odległość między Warszawą a Paryżem. Nie ma znaczenia, jak metoda wykona swoją pracę. Moglibyśmy ją nazwać odleglosc_warszawa_paryz, ale to jest na tym samym poziomie abstrakcji co zwracana wartość. Oznacza to, że nazwa metody sugeruje możliwe zwracane wartości. Taki sposób nazywania jest zbyt szczegółowy.

      W przyszłości miasta mogą zostać zmienione na inne, na przykład: Nowy Jork i Londyn. Dlatego nazwa odleglosc_warszawa_paryz stanie się przestarzała, a zmiana jej w każdym miejscu wiązałaby się z wysokimi kosztami. Najlepszym rozwiązaniem jest nazwać ją odleglosc. To dokładnie to, czego chcieliśmy — jeden poziom abstrakcji wyżej niż ciało metody.

      Po tej procedurze nasze dwie metody wyglądają jak poniżej:

      Poziom Abstrakcji i Nazwy Klas

      Metody i zmienne powinny być nazywane na poziomie abstrakcji wyższym niż ich treść, ale nazywanie klas to inna historia. Tworząc klasę, nie musimy przewidywać przyszłości. Nazwa klasy powinna opierać się na jej współczesnych założeniach. Nie oczekujemy, że samochód nabierze cech łodzi. Dlatego, jeśli obecne wymagania aplikacji wskazują na potrzebę samochodu, nazwa klasy powinna brzmieć Car zamiast Vehicle.

      Klasy podrzędne powinny być nazywane w ten sam sposób. Mając klasę Car, możemy dodać bardziej szczegółową wersję, na przykład CarPickup dla specjalnego typu Car, który ma większą przestrzeń ładunkową.

      Implikuje to, że zasada nazywania rzeczy na poziomie abstrakcji wyższym niż ich treść dotyczy metod i zmiennych, ale nie klas.

      Zasada pojedynczej odpowiedzialności

      Jedna z zasad SOLID mówi, że każdy moduł lub klasa powinny być odpowiedzialne tylko za jedną rzecz. Po prostu łatwiej jest nazwać element, który ma tylko jedną funkcję.

      Na przykład, jedyną odpowiedzialnością butelki jest bycie pojemnikiem na płyny. Nie powinniśmy dawać modułowi butelki możliwości poruszania się lub wykonywania innych rzeczy, które nie są prostą odpowiedzialnością butelki (w aplikacji). Jak nazwiesz pojemnik na płyny, który może się poruszać?

      To dość trudne, a butelka to tylko prosty przykład. Zamiast wymyślać chodzące (a potem być może tańczące, biegające i mówiące) butelki, lepiej zastosować zasadę pojedynczej odpowiedzialności. Stwórz jedną klasę dla pojemnika na płyny, nazwij ją Bottle, a drugą dla poruszającej się butelki, nazwij ją BottleCarrier.

      Zasada pojedynczej odpowiedzialności dotyczy również zmiennych. Każda zmienna powinna mieć tylko jedną odpowiedzialność, niezależnie od tego, czy jest zmienną metody, klasy czy innego rodzaju zmienną. Tak jak w przypadku nazywania klas, łatwiej jest nazwać zmienną, która ma tylko jedną odpowiedzialność.

      Rozważ Domenę Jako Zbiór Mniejszych Części

      Dobra architektura idzie w parze z dobrym nazewnictwem. Łatwiej jest nadawać nazwy rzeczom, gdy rozumiesz problemy, które rozwiązują. Jedną z technik, która pomaga zbudować lepszą architekturę, jest dzielenie każdej części zadania na małe kawałki. Ułatwi to i przyspieszy nadawanie nazw.

      Pomyśl o tym, czy nie lepiej jest nadawać nazwy modułom lub obiektom, gdy wiesz, jakie mają przeznaczenie? Powiedzmy, że musimy opisać samochód. Trudno jest nadać nazwę każdej funkcjonalności w jednej klasie, ale jeśli podzielimy to na wiele mniejszych części, okazuje się, że możemy stworzyć klasy Wheel, Tire, steeringWheel razem z innymi klasami dedykowanymi wszystkim innym elementom, które może zawierać samochód. Te mniejsze komponenty są łatwe do nazwania, a ich przeznaczenie jest łatwe do określenia. Dlatego, jeśli Twoje komponenty są trudne do nazwania, może to oznaczać, że masz problemy z architekturą aplikacji.

      Podsumowanie

      Każda dobra nazwa nadana zmiennej, metodzie, obiektowi lub klasie, prędzej czy później się opłaci. W moim artykule pokazałem kilka prostych technik, które pomogą Ci w nadawaniu dobrych nazw:

      • Przejdź na jeden poziom abstrakcji wyżej niż ciało (wszystko oprócz nazw klas)
      • Nazwa powinna opisywać odpowiedzialność klasy
      • Szanuj zasadę pojedynczej odpowiedzialności (jedna z zasad SOLID)
      • Podziel problemy na mniejsze części

      Dobre nazewnictwo nie musi być trudne. Naprawdę warto poświęcić trochę czasu na nadawanie rzeczy właściwych nazw. Korzystając z powyższych wskazówek, proces ten stanie się szybszy.

      Ten artykuł został zainspirowany książką „99 Bottles of OOP”, napisaną przez Sandi Metz i Katrinę Owen. Zachęcam do jej przeczytania. Oprócz tego, jak nazywać rzeczy, dowiesz się o dobrych praktykach refaktoryzacji kodu.

      Może to początek pięknej przyjaźni?

      Jesteśmy dostępni dla nowych projektów.

      Contact us