Jeden Poziom Indentacji
Kolejna zasada która niezmiernie może poprawić jakość naszego kodu . Stosujmy tylko jeden poziom indentacji na metodę .
Czy to ma sens?
Co w przypadku gdy wykonujemy pętlę w pętli? Przecież wtedy mamy już aż trzy poziomy indentacji. Więc ta zasada nie jest praktyczna, prawda? Może tak, ale może nie...
Przykład słabego kodu
public function filterBy($accountType)
{
$filtered = [];
// 0
foreach($this->accounts as $account)
{
// 1
if($account->type() === $accountTypen)
{
// 2
if($account->active())
{
// 3
$filtered[] = $account;
}
}
}
}
W powyższym przykładzie mamy 3 poziomy indentacji... A to przecież bardzo prosta metoda! Stać nas na więcej .
Często tak wiele poziomów indentacji (szczególnie w tak prostej metodzie) jest wskazówką dla nas, że przydałoby się tutaj wyabstrahować co nieco .
Jak to zrobić?
Należy skupić się wtedy na miejscu w którym mamy zagnieżdżenie. Następnie należy rozpracowywać to od środka aż do zewnątrz - pozbywając się nadmiarowych indentacji.
Mamy wiele opcji na poradzenie sobie z tym problemem.
Łączenie warunków
Korzystajmy z możliwości łączenia warunków - mamy przecież operatory logiczne. Nie stosujmy zagnieżdżonych warunków kiedy możemy wyjść zwycięsko z jednym warunkiem.
Ale przecież to brzydko wygląda i ciężko się czyta... To prawda. Musimy czytać, parsować (w głowie), myśleć... tracimy cenny czas i energię.
Jaka rada? Możemy dla przykładu wyodrębnić ten kod do osobnej metody z ładną, czytelną i opisową nazwą . Wówczas nawet komentarz do kodu (jeśli by był) staje się zbędny . Jest to znak, że jesteśmy na dobrej drodze. Mamy czytelną metodę, która dokładnie opisuje co tak naprawdę sprawdzamy. Dodatkowo kod ten jest teraz reużywalny - super.
Wykorzystywanie natywnych funkcji języka
Dla przykładu - pętla foreach nie jest akurat w tym przypadku dobrym wyborem. Może zamiast tego powinniśmy użyć natywnej funkcji języka php do filtrowania tablic ? W końcu dokładnie po to została ona stworzona.
public function filterBy($accountType)
{
return array_filter($this->accounts, function($account) use ($accountType)
{
return $account->isOfType($accountType);
});
}
Spójrz teraz. Wynik jest ten sam. Osiągnęliśmy dokładnie to samo. Ale mamy dokładnie jeden poziom indentacji, gdzie na początku mieliśmy aż trzy! Poprawiliśmy znacząco design i czytelność naszego kodu .
A wyobraź sobie, gdybyśmy mieli w poprzednim przykładzie słabego kodu dodatkowo warunki else, gdzie nasza logika by się rozgałęziała... A to wszystko ma tendencję do rozrostu. Za kilka miesięcy będziesz miał problem z czytaniem i analizowaniem takiego kodu. A co z innymi ludźmi? No właśnie... Taki kod jest niestety bardzo trudny do zrozumienia (w stosunku do wersji po refaktoryzacji).
Drobna uwaga
Kod, który wcześniej wyodrębniliśmy do osobnej metody, powinniśmy zamiast tego zastosować w modelu. To obowiązek modelu, by nam mówić, czy ma taki stan czy inny. Dodatkowo zyskujemy dużo większą elastyczność oraz reużywalność kodu. Oraz bardziej stosujemy się do dobrych praktyk i zasad programowania. Pozbywamy się również poprzednich metod w modelu z publicznego interfejsu - teraz są zbędne. A czym były? Jedynie ładnie nazwanymi getterami.
Powinniśmy pytać model zamiast wysyłać mu wiele żądań, by nam coś zwrócił byśmy sprawdzali to na własną rękę .
Podsumowując
Stosujmy jeden poziom indentacji per metodę . Warto stosować się do tej zasady, ponieważ prowadzi ona nas do bardzo wielu zalet. Reużywalność, SRP, design, OCP... Jednym słowem - pozwala nam poprawić jakość naszego kodu .
Kończąc
Dziękuję ci za lekturę tego artykułu drogi czytelniku mojego bloga . Jeśli uważasz, że ten artykuł był dla ciebie jakkolwiek przydatny i wyciągnąłeś z niego choć odrobinę wartości, to proszę podziel się nim z innymi oraz zostaw komentarz . Daj znać co o nim sądzisz .
Zapraszam cię również do lektury innych moich artykułów . Szczególnie tych dotyczących refaktoryzacji oraz zasad/reguł/rad odnośnie programowania .
A tymczasem życzę ci dobrego dnia, bywaj!