Projektowanie Obiektowe Refactoryzacja. Wykład 11 1

Podobne dokumenty
Etap implementacji. Refaktoryzacja

Pielęgnacja kodu: refaktoryzacja. Jacek Starzyński, ZETiIS PW

Cuchnące testy Systematyka, objawy, leczenie. Bartosz Walter

Polimorfizm. dr Jarosław Skaruz

Wzorce projektowe i refaktoryzacja

Programowanie obiektowe

Projektowanie obiektowe oprogramowania Wykład 4 wzorce projektowe cz.i. wzorce podstawowe i kreacyjne Wiktor Zychla 2017

Dziedziczenie. dr Jarosław Skaruz

Refaktoryzacja do wzorców projektowych

C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie. C++ - dziedziczenie C++ - DZIEDZICZENIE.

Refaktoryzacja. Na podstawie

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Projektowanie obiektowe oprogramowania Wykład 4 wzorce projektowe cz.i. wzorce podstawowe i kreacyjne Wiktor Zychla 2015

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Referencje do zmiennych i obiektów

TEMAT : KLASY DZIEDZICZENIE

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Podstawy programowania obiektowego

Klasy abstrakcyjne, interfejsy i polimorfizm

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Programowanie obiektowe

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

class Student Deklaracja klasy Osoba: Deklaracja klasy Student:

Enkapsulacja, dziedziczenie, polimorfizm

Aplikacje w środowisku Java

Pola i metody statyczne. Klasy zawierające pola i metody statyczne

Wzorce Strukturalne. Adapter: opis. Tomasz Borzyszkowski

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Klasy Obiekty Dziedziczenie i zaawansowane cechy Objective-C

Programowanie w Javie 1 Wykład i Ćwiczenia 3 Programowanie obiektowe w Javie cd. Płock, 16 października 2013 r.

Technologie i usługi internetowe cz. 2

What Is Refactoring?

Inżynieria Wytwarzania Systemów Wbudowanych

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

private - oznacza, że wszystkie elementy klasy bazowej zmieniają się w prywatne.

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Programowanie komputerowe. Zajęcia 7

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

Projektowanie klas c.d. Projektowanie klas przykład

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie obiektowe

Java: interfejsy i klasy wewnętrzne

2.4 Dziedziczenie. 2.4 Dziedziczenie Przykłady programowania w C - kurs podstawowy

Kurs programowania. Wykład 13. Wojciech Macyna. 14 czerwiec 2017

Programowanie obiektowe

TEMAT : KLASY POLIMORFIZM

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

Zaawansowane programowanie w języku C++ Klasy w C++

Wykład 6: Dziedziczenie

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Wykład 7: Pakiety i Interfejsy

Programowanie obiektowe Wykład 6. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/14

Wprowadzenie do refaktoryzacji

Materiały do zajęć VII

Programowanie obiektowe

Programowanie obiektowe

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Programowanie obiektowe i język Java

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

1. CZYM JEST SERIALIZACJA

Wykład 5: Więcej o Klasach i Metodach

Zaawansowane programowanie w C++ (PCP)

Klasy i obiekty cz II

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Analiza i projektowanie obiektowe 2016/2017. Wykład 11: Zaawansowane wzorce projektowe (1)

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Języki i metody programowania Java. Wykład 2 (część 2)

Podstawy Języka Java

Programowanie obiektowe

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Informatyka I. Dziedziczenie. Nadpisanie metod. Klasy abstrakcyjne. Wskaźnik this. Metody i pola statyczne. dr inż. Andrzej Czerepicki

Programowanie Obiektowe i C++

Języki i techniki programowania Ćwiczenia 4 Wzorce

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Dzisiejszy wykład. Wzorce projektowe. Visitor Client-Server Factory Singleton

Diagramy klas. dr Jarosław Skaruz

Problemy projektowania obiektowego. Czy podobne problemy można rozwiązywac w podobny sposób?

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Zaawansowane programowanie w języku C++ Programowanie obiektowe

Programowanie obiektowe

Katalog przekształceń refaktoryzacyjnych cz. I

Programowanie w Javie 1 Wykład i Ćwiczenia 2 Przegląd podstawowych klas w Javie (elementy programowania obiektowego) Płock, 16 października 2013 r.

Wstęp do programowania obiektowego. Wykład 2

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Języki i metody programowania Java INF302W Wykład 2 (część 1)

Fragmenty są wspierane od Androida 1.6

Programowanie 2. Język C++. Wykład 3.

Programowanie obiektowe i C++ dla matematyków

Programowanie, część I

Wstęp. Ale po co? Implementacja

Język ludzki kod maszynowy

Dziedziczenie. Tomasz Borzyszkowski

Konstruktor kopiujacy

Programowanie obiektowe

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

Transkrypt:

Projektowanie Obiektowe Refactoryzacja 1

Refactoryzacja Dokonywanie zmian w kodzie w celu uczynienia go latwiejszym do zrozumienia i wprowadzenia zmian, bez zmiany jego widocznego (zewnetrznego) zachowania. 2

Po co refaktoryzować? Refaktoryzacja polepsza projekt/architekture oprogramowania. Refaktoryzacja ulatwia zrozumienie kodu. Refaktoryzacja ulatwia szukanie bledow. Refaktoryzacja przyspiesza programowanie. 3

Zanim zrefaktoryzujesz Tests!!! Unit Regression Version Control 4

Is design dead? Czy refaktoryzacja umożliwia rezygnację z projektowania? 5

Code smells (stinks) Zapachy (smrody) kodu. If it stinks, change it. Grandma Beck Bloaters (Nadymacze) Object Orientation abusers Change preventers Dispensables Couplers 6

Bloaters Nadymacze Long Method Large Class Primitive Obsession Long Parameter List Data Clumps

Long Method Dlugie metody sa trudniejsze do zrozumienia. Powinny zostac podzielone na mniejsze metody ktorych nazwa adekwatnie oddaje ich funkcje. Dobrze nazwana krotka funkcja jest czytlniejsza niz kod. tmp=a;a=b;b=tmp; //swap(a,b); set[index[i]]=set[last]; index[last]=index[i];last ; Najczestsza refaktoryzacja w tym przypadku jest Extract Method Nowe srodowiska programistyczne ulatwiaja przegladanie takiego kodu umozliwiajac latwe nawigowanie pomiedzy wywolaniem fukcji, a jej kodem.

Large Class Rozbudowana klasa, rowniez jest trudna do zrozumienia. Czesto wskazuje na to, ze klasa ma za duzo opowiedzialnosci. Klasa powinna byc odpowidzialna wylacznie za jedno zadanie. Klasa moze miec za duzo zmiennych jak i za duzo metod. Najczestsza refaktoryzacja jest Extract Class.

Long Parameter List Podatna na bledy trudnosci z zapamietaniem kolejnosci i znaczenia i na zmiany

Data Clumps Kilka zmiennych (danych) ktore zawsze uzywane sa razem.

Primitive Obsession Uzywanie typow wbudowanych, zamiast klas dla prostych typow np. Money, Dlugosc it. Kompilator nie moze wykryc blednego przypisania typow. W C/C++ typedef wprowdza tylko alias, a nie nowy typ.

Object Orientation abusers Switch Statements Temporary Field Refused Bequest Alternative Classes with Different Interfaces

Switch Statements Czesto prowadzi do powielania kodu: ta sama instrukcja uzywana jest w wielu miejscach programu Dodanie nowego warunku wymaga znalezienia i zmiany wszystkich takich instrukcji. Nalezy rozwazyc wykorzystanie polimorfizmu. To moze wymagac utworzenia odpowiednich typow.

Temporary Field Przypadek pol, ktore sluza tylko kilku metodom, np. do przekazywania parametrow pomiedzy wywolaniami kilku metod. Zlozone struktury, Bufory itp. Nie odnosza sie do calej klasy.

Refused Bequest nie przyjeta darowizna Klasa dziedziczaca, nie wykorzytuje (nie przyjmuje) implementacji klasy nadrzednej, tzn dziedziczymy tylko czesc zachowania/implementacji. Moze to oznaczac zla strukture klas i nawet zlamanie zasady podstawiania Liskov. Klasa dziedziczaca, nie przyjmuje interfejsu klasy nadrzednej, np. dziedziczenie prywatne w C++. Dziedziczymy tylko implementacje.

Alternative Classes with Different Interfaces Metody w roznych klasach robia to samo, ale maja rozna sygnature/nazwy write, print etc. Dwie klasy robia podobne rzeczy. Nalezy alboje polaczyc, albo przeniesc wspolne zachowanie do nadklasy.

Change preventers Divergent Change Shotgun Surgery Parallel Inheritance Hierarchies

Divergent Change Zlamanie zasady pojedynczej odpowiedzialnosci. Klasa jest zmieniana czesto z kilku roznych powodow.

Shotgun Surgery Jedna zmiana, wymaga zmiany wielu klasach.

Parallel Inheritance Hierarchies Dwie lub wiecej rownoleglych hierarchi klas. Dodanie podklasy, w jednej hierarchi wymaga zmian w drugie. Zasadniczo jest odmiana zapachu Shotgun Surgery. Powstaje naturalnie, nie jest dla mnie jasne jak bardzo to smierdzi:)

Dispensables Lazy class Data class Duplicate Code Dead Code Speculative Generality

Data class Klasa ktora jest wylacznie opakowaniem na dane. Tzn. zawiera tylko pola oraz metody dostepowe. Wydaje mi sie, ze to kloci sie z zaleceniami dotyczacymi kilku innych zapachow...

Lazy class Klasa ktora robi za malo i nie zarabia na siebie.

Duplicate Code Straszny smrod! Powielanie tego samego lub bardzo podobnego kodu wielu miejscach. Zwykle wynik copy & paste. Utrudnia wprowadzanie zmian.

Dead Code Kod ktory nigdy nie jest wykonywany.

Speculative Generality Kod ktory jest pisany na zapas. Kod ogolny jest bardrdziej skomplikowany, a co za tym idzie trudniejszy do zrozumienia i utrzymania.

Couplers Feature Envy Inapriopriate Intimacy Message Chains Middle Man

Feature Envy Metoda/klasa ktors zbyt czesto korzysta z danych z innej klasy bardziej niz z danych z pol wlasnej klasy.

Inapriopriate Intimacy Klas ktora korzysta zby czesto z prywatnych pol innej klasy.

Message Chains Dluga sekwencja geterow.

Middle Man Naduzycie delegacji Klasa deleguje wiekszosc metod do innej klasy chyba, ze to jest proxy lub dekorator.

Inne Comments Incomplete Library Class 33

Comments Komentarze moga sluzyc jako dezodorant ktory przykrywa przykre zapachy. Komentarze moga sugerowac ktore czesci kodu sa niezrozumiale i wymagaja refaktoryzacji.

Incomplete Library Class Biblioteka ktora musimy dostosowac lub rozszerzyc do naszyhc potrzeb bez dostepu do jej kodu zrodlowego.

Refactorings (z Refaktoryzacja M. Fowler) Composing methods Moving Features Between Objects Organizing Data Simplifying Conditional Expression Making Method Calls Simpler Dealing with Generalization Big Refactorings

Rename method Extract method Move Method Extract Subclass Hide Delegate Introduce Foreign method Decompose Conditional

Rename method Dodaj nowa metode o nowej nazwie. Skopiuj do niej implementacje starej metody. Zamien implementacje startej metody na wywolanie nowej metody. Pozamieniaj w w kodzie wywolania starej nazwey na nowa nazwe. Usun stara metode. Jesli nie mozesz jej usunac bo jest czescia interfejsu, oznacz ja jako deprecated.

Extract method Stworz nowa metode o adekwatnej nazwie. Przekopiuj wyciagany kod ze starej metody do nowej. Sprawdz, czy kod zawiera zmienne lokalne (temporary) dla starej metody. Uzyj Split Temporary Variable jesli trzeba. Zmienne ktore wystepuja wylacznie w wyciaganym kodzie, stana sie zmiennymi lokalnymi nowej metody. Zmienne lokalne ktorych kod nie modyfikuje, stana sie parametrami nowej metody.

Extract Method modufikowane zmienne lokalne Znajdz zmiene lokalne ktore wyciagniety kod modyfikuje. Jesli jest tylko jedna, to sprobuj przypisac do niej wynik nowej funkcji. Jesli to trudne lub jest ich wiecej to zastosuj Replace Temp with Query. Jesli to nie pomoze, to zrezygnuj z faktoryzacji, lub zastosuj Replace Method with Method Object.

Split Temporary Variable FILE *out=fopen( test.cfg, r );... fclose(out); out=fopen( results.dat, w );... fclose(out);

Split Temporary Variable FILE *out=fopen( test.cfg, r );... fclose(out); out=fopen( results.dat, w );... fclose(out); const FILE *test_file=fopen( test.cfg, r );... fclose(test_file); const FILE *result_file=fopen( results.dat, w );... fclose(result_file);

Replace Temp with Query void some_method() { int total_n_pixels=n_pixels_in_row_*n_pixels_in_row_; for(int i=0;i<total_n_pixels;++i) { }...

Replace Temp with Query void some_method() { int total_n_pixels=n_pixels_in_row_*n_pixels_in_row_; for(int i=0;i<total_n_pixels;++i) { }... int total_n_pixels() const { return n_pixels_in_row_*n_pixels_in_row_; } void some_method() { for(int i=0;i<total_n_pixels();++i) { }...

Replace Method with Method Object. Jesli jakas metoda zawiera duzo zmiennych lokalnych (temporary) to mozemy ja zamienic w obiekt fukcyjny. Tworzymy nowa klase o takiej samej nazwie jak metoda. W tej klasie tworzymy pole dla obiektu ktory zawiera zamieniana metode oraz dla kazdego parametru i zmiennej lokalnej metody. Dodajemy konstrutor ktory przyjmuje orginalny obiekt i parametry. Tworzymy metode o nazwie np. compute(). Przenosimy do niej kod ze starej metody. Poniewaz zmienne lokalne sa teraz polami nowej klasy mozemy spokojnie podzielic metode na mniejsze

class SomeClass { int long_and_complicated_method(int arg) { int tmp1,tmp2,tmp3; return...; } }

class SomeClass { int class long_and_complicated_method(int LongAndComplicatedMethod { arg) { int LongAndComplicatedMethod(SomeClass tmp1,tmp2,tmp3; &some_class, int arg) :some_class_(some_class), arg_(arg) {}; int compute() {...} return private:...; } SomeClass &some_class_; int arg_; } int tmp1,tmp2,tmp3; }

class SomeClass { int class long_and_complicated_method(int LongAndComplicatedMethod { arg) { int LongAndComplicatedMethod(SomeClass tmp1,tmp2,tmp3; &some_class, int arg) :some_class_(some_class), SomeClass { arg_(arg) {}; int compute() {...} return private: int...; long_and_complicated_method(int arg) { } SomeClass return LongAndComplicatedClass(*this,arg).compute(); &some_class_; int } arg_; } int tmp1,tmp2,tmp3; } }

Automatyczna refaktoryzacja Wiekszosc srodowisk programistycznych posiada narzedzia do automatycznej rekatoryzacji. Zwykle jednak tylko kilku i to o okrojonych mozliwosciach. 49