Churn PHP – zaplanuj refactoring!

Churn PHP – zaplanuj refactoring!

Yarrr!

Refactoring – w tym wpisie chciałbym przedstawić Wam problem z nim związany. Mianowicie: od czego zacząć? Na czym się skupić? Co najbardziej wymaga zmian i przepisania w naszym systemie? Myślę, że te pytania napotykamy za każdym razem, gdy chcemy poświęcić trochę czasu na poprawienie jakości kodu w aplikacji. A więc jak to jest?

Refactoring to nie czynność naprawcza! To jeden z etapów programowania.

Tak, dokładnie! Co ważne – zamiast planować co sprint kolejne akcje związane ze zmianami kodu pod kątem przejrzystości, wydajności – przemyśl wszystko od razu. Poświęcenie paru godzin na rozplanowanie architektury konkretnej funkcjonalności pozwoli oszczędzić krotność tego czasu w późniejszych etapach rozwoju aplikacji. W momencie, gdy zaczynamy pracę nad nową opcją – przejrzyjmy klasę od której rozpoczynamy pracę. Niech to będzie chociażby serwis związany z zarządzaniem użytkownikami. Widzisz coś, co można byłoby zrobić lepiej? Popraw to! Przemyśl każdą opcję, może warto byłoby wydzielić jakiś fragment kodu do nowej klasy? Może wszystko da się skrócić i ujednolicić?

Let’s do it! Pamiętaj jednak, by nie wychylać się ze swoimi zmianami poza obręb rozwijanej w danym momencie klasy. Najlepiej, aby refactoring przeprowadzać małymi krokami, z czasem zauważysz poprawę w całym systemie. Oczywiście czasami nie da się wszystkiego przewidzieć na samym początku planowania – więc przyjdzie kolej na zmiany w obrębie całej warstwy. Tutaj zaczyna się zabawa i z pomocą przychodzi nam narzędzie jakim jest Churn PHP autorstwa Billa Mitchella.

Churn PHP – czym jest?

Przed Wami narzędzie służące wynajdywaniu miejsc w aplikacji, które zasługują na zmiany, poprawki i optymalizację. W praktyce  jest to paczka napisana w PHP, która wynajduje pliki, których zarówno złożoność cyklomatyczna jak i częstotliwość edycji jest wysoka.

Mamy tutaj pojęcie Cyclomatic Complexity (złożoność cyklomatyczna), które określa stopień złożoności logiki kodu. Jeżeli jakaś metoda zawiera kilka instrukcji warunkowych, pętli czy switchy – zwiększa się jej poziom trudności zrozumienia dla innych programistów, ale także dla samego interpretera. Im wyższa złożoność tym kod jest bardziej podatny na błędy, gdyż może się zadziać w danym miejscu zbyt dużo niekontrolowanych przypadków. Tak napisane klasy, czy metody ciężej jest też pokryć testami (nie tylko jednostkowymi). Metryka ta określa tym samym niestabilność systemu w ustalonej skali. Cytując Wikipedię…

od 1 do 10 – kod dość prosty stwarzający nieznaczne ryzyko

od 11 do 20 – kod złożony powodujący ryzyko na średnim poziomie

od 21 do 50 – kod bardzo złożony związany z wysokim ryzykiem

powyżej 50 – kod niestabilny grożący bardzo wysokim poziomem ryzyka.

Najlepiej trzymać się oczywiście poniższej najniższego poziomu niebezpieczeństwa. Osobiście podczas pisania ostatniej aplikacji uzyskałem złożoność w najwyższym momencie wynoszącą 8 (był to jeden z serwisów). Myślę, że to świetny wynik i jeżeli uda się Wam uzyskać nawet wartość 10-12, to będzie to naprawdę sympatyczna wartość!

Kolejnym czynnikiem, który jest niezwykle istotny podczas refactoringu jest liczba edycji konkretnej klasy (pliku). Pomyślicie, że to nic takiego, prawda? Nic bardziej mylnego! Wysoka częstotliwość edycji Waszej klasy oznacza, że nie spełnia ona jednej z podstawowych zasad SOLID-a, a mianowicie Open/Close Principle. Kod, który wytwarzamy powinien być łatwy do rozbudowania bez konieczności edycji. Najłatwiej uzyskać zgodność z tą zasadą jest poprzez korzystanie z wzorców projektowych, które z zasady pokazują nam jak budować kolejne komponenty systemu.

Churn podgląd wyników

  • Klasy, które nie są często aktualizowane, ani nie posiadają wysokiej złożoności to najlepszy kod jaki możemy mieć. Te miejsca zostawiamy na boku, wszystko jest w jak najlepszym porządku.
  • Klasy, które są często edytowane, aczkolwiek nie posiadają wysokiej złożoności to kod, który nie do końca spełnia zasady czystego kodu, gdyż wymaga częstych zmian, ale jest to prosty skrypt. W razie problemów bardzo łatwo coś naprawimy.
  • Klasy, które są rzadko edytowane, aczkolwiek zawierają wysoki poziom logiki to miejsce narażone na występowanie problemów, ale… no właśnie – tutaj wszystko działa, a póki działa możemy znaleźć większych kandydatów na zmiany. Tutaj nie wprowadzamy częstych poprawek, zmian – dopóki to się nie zmieni, to możemy zaczekać z refactoringiem i zająć się ostatnią pozycją z naszej listy.
  • Klasy, których kod zarówno często się zmienia, jak i jest stosunkowo złożony i niezrozumiały. To do tego miejsca rzucamy się czym prędzej i analizujemy problem. To ten kod może najszybciej przysporzyć problemów. Refactoring obowiązkowy!

Churn PHP wylicza nam wynik dla poszczególnych klas aplikacji i wykazuje którymi miejscami powinniśmy zająć się w pierwszej kolejności.

Obsługa narzędzia.

Jeżeli zaciekawiłem Was naszym tytułowym tematem, to chciałbym w tym miejscu opisać możliwości oraz funkcje, które daje nam Churn. Myślę, że wszystko to znajdziecie także na GitHubie projektu, aczkolwiek nie zaszkodzi przekazać dodatkowy raz tych informacji.

Instalacja za pomocą composera jest bardzo prosta, wystarczy dołączyć do naszego pliku composer.json parametr bmitch/churn-php – oczywiście mowa tutaj o sekcji DEV, co by nie dorzucać zbędnej paczki w trybie produkcyjnym. Chociaż moim zdaniem najlepszym rozwiązaniem jest uruchomienie globalnej komendy instalacyjnej, aby móc sprawdzać wszystkie swoje projekty.

# Command line:

composer global require bmitch/churn-php

Po zakończeniu instalacji możemy zaczynać pracę z narzędziem. Wszystko wykonujemy z poziomu konsoli. Przykładowe uruchomienie Churna wykonujemy uruchamiając komendę churn run (dla lokalnej instalacji ./vendor/bin/churn run) a później należy podać katalogi, które chcemy poddać analizie wykonanej przez naszą paczkę. Przykładowe wywołanie komendy w aplikacji wykonanej w oparciu o framework Laravel.

# Command line:

churn run app

Powyższa komenda wykona dokładną analizę naszego katalogu z klasami aplikacji, pominiemy badanie plików vendora, które nie powinny nas obchodzić. Dodatkowo możemy w bardzo prosty sposób rozbudować konfigurację i ustawić wykluczane pliki, określić minimalny score, który zasugeruje refactoring konkretnej klasy. Więcej informacji znajduje się w tym miejscu. Na koniec dodam także, że sama paczka wymaga do funkcjonowania zainstalowanego PHP w wersji minimalnie 7.0, oraz tego by nie pracować na systemie operacyjnym jakim jest Windows. Churn jest wspierany jedynie przez normalne systemy takie jak OSX czy różne dystrybucje Linuxa.

Mam nadzieję, że narzędzie przyda się Wam do prac nad poprawą jakości kodu aplikacji. Tak jak na początku tekstu wspomniałem – zalecam jednak uruchamianie churna w trakcie developmentu, przed każdym commitem warto sprawdzić czy wszystko w naszej funkcjonalności gra tak jak powinno.

  • :)

    Hmm, bardzo ciekawy i obiecujący blog. Czekam na kolejny wpis! 🙂

Comments are closed.