Wiem, że refaktoryzacja to „zmiana struktury programu tak, aby funkcjonalność się nie zmieniała”. Rozmawiałem z kilkoma chłopakami pracuję z na mój projekt końcowej roku na Uniwersytecie i byłem zaskoczony, że mają one znacznie bardziej rozległy (z braku lepszego słowa) widok refactoring.
Uważam, że refaktoryzacja polega na wyodrębnianiu metod i zmianie nazw klas. Zaproponowali także takie rzeczy, jak zmiana struktur danych (takich jak Java LinkedList
na an ArrayList
), zmiana algorytmów (użycie sortowania przez scalanie zamiast sortowania bąbelkowego), a nawet przepisywanie dużych fragmentów kodu jako refaktoryzacji.
Byłem całkiem pewien, że się mylili, ale nie byłem w stanie podać dobrego powodu, ponieważ to, co sugerowali, zmieniło program (i prawdopodobnie poprawiło) bez zmiany jego zachowania. Czy mam rację, a co ważniejsze, dlaczego?
źródło
Fowler rysuje czystą linię między zmianami w kodzie, które to robią, a tymi, które tego nie robią, wpływają na jego zachowanie. Tych, którzy tego nie robią, nazywa „refaktoryzacją”. To jest istotna różnica, bo jeśli dzielimy naszą pracę w refactoring i non-refactoring działania modyfikacji kodu (Fowler nazywa ją „nosi różne kapelusze”), możemy zastosować różne, cel-właściwe techniki.
Jeśli dokonujemy refaktoryzacji lub modyfikacji kodu zachowującej zachowanie:
Jeśli dokonujemy modyfikacji kodu zmieniającej zachowanie:
Jeśli stracimy z oczu to rozróżnienie, wówczas nasze oczekiwania dotyczące każdego zadania modyfikacji kodu są niejasne i złożone, a przynajmniej bardziej zagmatwane i bardziej złożone, niż gdybyśmy byli tego świadomi. Dlatego ważne jest słowo i jego znaczenie.
źródło
Aby wyrazić swój pogląd:
Małe, przyrostowe zmiany, które pozostawiają kod w lepszym stanie niż został znaleziony
Zdecydowanie tak: zmiany „kosmetyczne”, które nie są bezpośrednio związane z funkcjami (tj. Nie są rozliczane jako żądanie zmiany).
Zdecydowanie nie: przepisywanie dużych fragmentów w oczywisty sposób narusza część „małych, przyrostowych”. Refaktoryzacja jest często używana jako przeciwieństwo przepisywania: zamiast robić to ponownie, ulepsz istniejące.
Zdecydowanie być może: zastępowanie struktur danych i algorytmów jest przypadkiem granicznym. Decydującą różnicą w tym przypadku IMO są małe kroki: bądź gotowy do dostarczenia, bądź gotowy do pracy nad inną sprawą.
Przykład: Wyobraź sobie, że masz moduł Report Randomizer, który jest spowolniony przez użycie wektora. Zaprofilowałeś, że wstawianie wektorów jest wąskim gardłem, ale niestety moduł opiera się na pamięci ciągłej w wielu miejscach, więc podczas korzystania z listy rzeczy po cichu się psują.
Przepisanie oznaczałoby wyrzucenie modułu z budynku na lepszy i szybszy od zera, po prostu wybranie kilku elementów ze starego. Lub napisać nowy rdzeń, a następnie dopasować go do istniejącego okna dialogowego.
Refaktoryzacja oznaczałaby podjęcie małych kroków w celu usunięcia arytmetyki wskaźnika, tak aby przełącznik. Może nawet utworzysz funkcję narzędzia zawijającą arytmetykę wskaźnika, zastępując bezpośrednią manipulację wskaźnikiem wywołaniami tej funkcji, a następnie przełącz się na iterator, aby kompilator narzekał na miejsca, w których arytmetyka wskaźnika jest nadal używana, a następnie przełącz się na a
list
, a następnie usuń funkcja ultility.Pomysł polega na tym, że kod sam się pogarsza. Podczas naprawiania błędów i dodawania funkcji jakość spada małymi krokami - znaczenie zmiennej nieznacznie się zmienia, funkcja otrzymuje dodatkowy parametr, który przerywa izolację, pętla staje się nieco skomplikowana itp. Żaden z nich nie jest prawdziwym błędem, możesz Nie mów liczby linii, która sprawia, że pętla jest złożona, ale szkodzi czytelności i konserwacji.
Podobnie, zmiana nazwy zmiennej lub wyodrębnienie funkcji nie są same w sobie namacalnymi ulepszeniami. Ale razem walczą z powolną erozją.
Jak ściana z kamyków, w której codziennie upadamy na ziemię. I codziennie jeden przechodzień podnosi go i odkłada.
źródło
Mając na uwadze definicję Martina Fowlera,
... Myślę, że masz wyraźną rację.
Zmiana algorytmu na coś znacznie szybszego oczywiście nie jest refaktoryzacją, ponieważ zmienia się zachowanie zewnętrzne! (Z drugiej strony, jeśli efekt nigdy nie jest zauważalny, być może można by to nazwać refaktoryzacją - a także przedwczesną optymalizacją. :-)
To moje zwierzę irytacja; denerwujące jest, gdy ludzie używają tego terminu niechlujnie - spotkałem nawet takich, którzy mogliby przypadkowo użyć refaktoryzacji w zasadzie do jakiejkolwiek zmiany lub naprawy. Tak, to modne i fajne modne hasło iw ogóle, ale nie ma nic złego w prostych, starych terminach, takich jak zmiana , przepisanie lub poprawa wydajności . Powinniśmy ich używać, gdy jest to stosowne, i zarezerwować refaktoryzację w przypadkach, gdy naprawdę ulepszasz wewnętrzną strukturę swojego oprogramowania. Szczególnie w zespole programistów posiadanie wspólnego języka do dokładnego omawiania swojej pracy ma znaczenie.
źródło
Jeśli interfejs do fragmentu kodu ulegnie zmianie, uważam to za coś więcej niż refaktoryzację.
Typowy przypadek refaktoryzacji to
Oznacza to, że termin refaktoryzacja odnosi się do omawianego interfejsu. tj. mógłbyś refaktoryzować kod za jednym interfejsem, jednocześnie bardziej szeroko zmieniając kod innego na niższym poziomie (może to rozróżnienie powoduje zamieszanie między tobą a twoimi kolegami?)
źródło
Myślę, że masz rację, ale spór o znaczenie słowa nie jest szczególnie interesujący ani produktywny.
źródło
http://en.wikipedia.org/wiki/Code_refactoring
Zgadzam się, że kod refaktoryzacji obejmuje łamanie istniejącego kodu. Po prostu upewnij się, że masz testy jednostkowe, aby nie wprowadzać żadnych błędów, a reszta kodu się kompiluje. Korzystanie z narzędzi do refaktoryzacji, takich jak Resharper for C #, sprawia, że jest to takie proste!
źródło
Nie zgadzam się :
Znasz już dokładniejsze terminy używane dla podzbiorów refaktoryzacji i tak, jest to bardzo ogólne określenie.
źródło
Myślę, że nikt nie może skorzystać na zbyt mocnej definicji terminu „refaktoryzacja”. Granica między tym, jak to postrzegasz, a twoimi współpracownikami jest niewyraźna i może być bliższa ich lub twojemu poglądowi w zależności od wielu faktów. Ponieważ jest dynamiczny, spróbujmy go zdefiniować. Przede wszystkim zdefiniuj granice systemu lub podsystemu, który próbujesz refaktoryzować.
Jeśli jest to metoda, zachowaj nazwę, argumenty wejściowe, typ zwracanej wartości i ewentualnie poprawione wyrzucanie instrukcji. Zastosuj wszystkie zmiany wewnątrz metody bez zmiany sposobu, w jaki jest ona postrzegana na zewnątrz.
Jeśli zmienisz klasę, naprawisz jej publiczny interfejs API i użyjesz zmiennych zmiany nazwy, wyodrębnij metody i wszystkie inne dostępne techniki zmienią klasę, aby była bardziej czytelna i / lub wydajniejsza.
Jeśli część kodu, którą refaktoryzujesz, jest pakietem lub modułem, dokonaj refaktoryzacji wewnątrz niego, ewentualnie zmień nazwę klas, usuń, wprowadź interfejsy, wypchnij / wciągnij kod do super / podklas.
źródło
Refaktoryzacja = poprawa wymagań niefunkcjonalnych przy zachowaniu niezmienionych wymagań funkcjonalnych.
Wymagania niefunkcjonalne = modułowość, testowalność, łatwość utrzymania, czytelność, oddzielenie problemów, zasady liskov i tak dalej ...
źródło