piątek, stycznia 2

Refaktoryzacja to...

witam;

Postawiłem sobie osobiście cel pisania o JavaFX, nawet rozpocząłem jakieś przymiarki, ostatecznie miałem napisać kilka słów o JSF + Seam, ale pewnego dnia udało mi się przeczytać książkę o czymś innym ...

Refaktoryzacja to zmiany wewnętrznej struktury kodu programu, które mają za zadanie zwiększyć czytelność oraz obniżyć koszt wprowadzania zmian. Mówi się że, poprawnie przeprowadzona refaktoryzacja nie zmienia sposobu działania aplikacji od strony użytkownika.

Ta prosta definicja pozwala zapoznać się terminem refaktoryzacji, ale formalna definicja podana przez D.Roberts'a w 1998 ma postać:

R = (pre; T; P)

gdzie:
- pre - asercja która musi być spełniona by przekształcenie R było prawdziwe;
- T - transformacja kodu programu;
- P - funkcja przekształcająca warunki początkowe na warunki końcowe, określa warunki końcowe, które są prawdziwe po przeprowadzeniu transformacji T;

Refaktoryzacja ma za zadanie wprowadzić zmiany w nasz kod, ale zmiana struktury programu może stanowić dla niego ogromne zagrożenie, jeżeli by po jej zakończeniu program miał działać inaczej. Dlatego najważniejszym warunkiem poprawnie przeprowadzonej refaktoryzacji, jest zapewnienie, że nie wprowadzi ona żadnych zmian do działa aplikacji;


Ale jak można zweryfikować poprawności wprowadzanych zmian, istnieją dwie metody weryfikacji poprawności przekształceń:
  • analityczna - wykorzystanie statycznych informacji; metoda nie wymaga uruchomienia programu
  • dynamiczna - weryfikacja przeprowadzana przy pomocy testów; wymaga uruchomienia aplikacji
Podział metod weryfikacji poprowadził do powstania podziały przekształceń na:
  • proste - najczęściej zautomatyzowana weryfikacja przy pomocy IDE
  • trudne - weryfikacja wymaga testowania przy pomocy własnoręcznie napisanych testów
Oczywiście w prawdziwym świecie nie jest łatwo i dlatego liczba przekształceń trudnych jest o wiele większa niż występowanie przekształceń prostych;


Dalsza część posta będzie parta o publikację Martin Fowler Refactoring: Improving the Design of Existing Code w swojej książce przedstawił podział przekształceń ze względu na sposoby weryfikacji:
  • proste (ok. 22) - można zweryfikować analitycznie
  • trudne (ok.50)
    • testowalne (ok. 25) - wymagają z góry znanych testów
    • nieokreślone (ok. 25) - wymagają dedykowanych testów


Fowler zdefiniował pojęcie bad smell czyli jeżeli coś źle pachnie należy to zmienić. Pojęcie jest luźną definicją dlatego też obejmuje najróżniejesze problemy związane ze strukturą kodu. Dlatego też lista bad smells obejmuje wiele niespokrewnionych ze sobą problemów.

Problemów takich jak:
  • Dublicate Code (Z duplikowany kod)
  • Long Method (Długa metoda)
  • Large Class (Nadmiernie rozbudowana klasa)
  • Long Parameter List (Długa lista parametrów)
  • Comments (Nadmierne komentarze)
  • Incomplet Library Class (Niekompletna klasa biblioteki)
  • Switch Statements (Skomplikowane instrukcje warunkowe)
  • Message Chains (Łańcuch wywołań przez delegację)
  • Data Class (Klasa z danymi)
  • Data Clumps (Zbitka danych)
  • Refused Bequest (Odrzucony spadek)
  • Inappropriate Intimacy (Niewłaściwa hermetyzacja)
  • Lazy Class (Bezużyteczna klasa)
  • Feature Envy (Zazdrość o funkcje)
  • Paraller Inheritance Hierarchies (Równoległe hierarchiczne dziedziczenie)
  • Middle Man (Pośrednik)
  • Divergent Change (Zmiany z wielu przyczyn)
  • Shotgun Surgery (Odpryskowa modyfikacja)
  • Speculative Generality (Spekulacyjne uogulnienie)
  • ... obiecuje, że za jakiś czas pojawi się opis wszystkich bad smells


Po tak 'pięknej' liście należy się zastanowić jak znajdować bad smell. Z tym problemem nie pozostajemy sami istnieje kilka źródeł, które mogą dostarczyć danych o ich obecności:
  • intuicja programisty, która jest niemierzalna i trudna do zdefiniowania, a jednak pełni bardzo ważną rolę w identyfikacji złych praktyk obiektowych

  • metryki, które są podstawowym mechanizmem ilościowej oceny jekości projektu. Metryki dostarczają liczbowej i łatwej do zinterpretowania informacji o wielu aspektach jakości projektu

  • analiza Abstrakcyjnego Drzewa Składowego AST, które jest graficzną reprezentacją rozbioru gramatycznego programu. Obecność lub brak określonych elementów w drzewie AST wskazuje na obecność lub wyklucza obecność niektórych zapachów

  • informacja o innych zapachach pozwala wykorzystać znane już fakty o innych przykrych zapachach

  • analiza dynamiczna, która pozwala określić atrybuty programu nie dające zidentyfikować wyłącznie poprzez analizę statyczną. Przykładem analizy dynamicznej może być wykonanie przypadków testowych

  • historia zmian kodu pochodząca z repozytorium zarzadzania konfiguracją pozwala ocenić wpływ niektórych zmian na program


Słowem podsumowania...
może post jest przydługi, ale mam nadzieję, że zawarte informacje w nim komuś się przydadzą. Mi pozwolił nazwać rzeczy które od dawna robiłem.

1 komentarz:

  1. Nie wiem kim jest pan Roberts, ale chyba w zyciu rozwiązał wiecej całek niz napisał linijek kodu;P

    Swoją drogą ciekawe zestawienie 2 podejsc:
    przeteoretyzowane "R = (pre; T; P)"
    obok praktycznych i realnych az do bólu smrodków Fowlera:)

    OdpowiedzUsuń