Ruby pozwala w bardzo czytelny sposób odwoływać się do klas. Warto wykorzystać to aby poprawić przejrzystość projektu. Idealnie jest, jeśli patrząc na nazwę klasy od razu wiadomo co robi i co jest wynikiem jej działania. Podobne podejście można również stosować w Railsach. Service objects są dobrym przykładem gdzie świetnie się to sprawdza. Zamiast nazywać klasę OrderService, lepiej użyć namespace które powie coś więcej o zamówieniu
Stałe, Moduły i Klasy w Ruby
W ruby każda “zmienna” zaczynająca się dużą literą jest stałą. Dotyczy to również nazw klas oraz modułów. Stałe zorganizowane są w strukture drzewiastą przypominającą strukture plików i katalogów. Można wyobrażać sobie klasy i moduły jako katalogi, natomiast zwykłe stałe jako pliki. Tak jak w systemie plików każdy katalog oraz plik ma własną unikalną ścieżkę, tak samo w ruby do każdej stałej odwołujemy się w po jej “ścieżce”
module Customer class Discount TAX = 20% ... end end Customer::Discount::TAX # 20%
Aby wyświetlić stałą TAX musimy podać pełną “ścieżkę” do niej. Ale gdybyśmy chcieli odwołać się do niej z innego poziomu(scope),np z poziomu modułu ścieżka wyglądałaby inaczej
module Customer Discount::TAX # 20% class Discount TAX = 20% end end
zawsze możemy również zdefiniować bezwzględną ścieżkę, dokładnie tak samo jak w systemie plików. Jest ona poprzedzona :: czyli w naszym przypadku będzie ::Customer::Discount::TAX
Nazewnictwo modułów i klas w rails-ach
Aby wykorzystać autoload rails-ów trzeba nazywać katalogi zgodnie z nazwą modułów, a pliki zgodnie z nazwą klas. Zakładając, że katalog services jest dodany do autoloadu. Wtedy klasa:
Customer::Discount powinna się znaleźć w app/services/customer/discount.rb
Admin::RejectOrder powinna się znaleźć w app/services/admin/reject_order.rb
Warto zwrócić uwagę, że Moduł + Klasa + nazwa metody to trzy słowa które pozwalają nam w sposób bardzo precyzyjny określić co dana metoda ma robić. Zawsze trzeba sobie zadać pytanie czy jeśli pokażemy innemu programiście/nie programisćie taką 3-czlonową nazwę, to czy będzie rozumiał co metoda robi bez jej czytania. Jesli tak, to nazwa jest dobra. Czasem wystarczą tylko dwa słowa (moduł + klasa), aby dokładnie określić co dana meteda wykonuje. w takim przypadku najlepiej na nazwę metody pasuję słówko call, które dodatkowo pozwala na uproszczony syntax. Kilka przykładów:
Admin::ChangeNurseStatus.new.call
Admin::CreateInactiveNurse.new.call
Nurse::AreaUpdate.new.from_geo_json
Invoice::NumberGenerator.next
Tego typu nazewnictwo pozwala wrócić do projektu po kilku miesiącach i wiedzieć od razu w którym pliku szukac danej funkcjonalności. Jesli na projekt trafia nowa osoba, to po samej strukturze plików jest w stanie mniej więcej zorientować się co aplikacja robi.
Nazewnictwo modułów
Jako nazwę modułu warto zasatosować coś co pozwoli nam podzielić projekt na mniejsze części. Często może to być zwiazane z jakimś ‘aktorem’ w systemie, Np Admin, Patient, Customer, ale może to być również coś istotnego, co checmy wydzielić np Car, Callendar itp.
Ważne aby zalazło się kilka klas, które bedziemy mogli wrzucić do tego modułu. Trzeba również zwrócić uwagę na konflikt nazw. Jeśli np mamy model (klase) Car to nie możemy w tym samym ‘scope’ nazwać tak modułu. W takiej sytuacji trzeba albo użyć liczby mnogiej np. Cars::Engine.new.calculate_power albo użyć dodatkowego prefixu. Dla service objectów może to być Service albo UseCase
Podsumowanie
Najważniejsze to nazywać klasy tak, aby siadając do projektu po długiej przerwie, móc się efektywnie w nim odnaleźć. Ruby daje nam naprawde duże możliwości. Wystarczy z nich skorzystać aby projekt był czytelny i przejrzysty.