Etap implementacji. Refaktoryzacja



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

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

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

Katalog przekształceń refaktoryzacyjnych cz. I

Wzorce projektowe i refaktoryzacja

Wprowadzenie do programowania aplikacji mobilnych

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

O czym dzisiaj? krótko o refaktoryzacji; dźwięki w Android; aparat w telefonie; Baza danych; GPS.

Wprowadzenie do refaktoryzacji

What Is Refactoring?

Środowisko NetBeans. Paweł Boguszewski

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

Programowanie obiektowe

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

Diagramy klas. dr Jarosław Skaruz

Polimorfizm. dr Jarosław Skaruz

Platformy Programistyczne Podstawy języka Java

Programowanie obiektowe

Podstawy programowania III WYKŁAD 6

TESTOWANIE OPROGRAMOWANIA

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

Wzorce projektowe. dr inż. Marcin Pietroo

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

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

Technologie i usługi internetowe cz. 2

Wzorce Strukturalne. Adapter: opis. Tomasz Borzyszkowski

Modelowanie i Programowanie Obiektowe

Singleton. Cel: Przykład: Zastosowanie: Zapewnienie, że klasa ma tylko jedną instancję i dostarczenie globalnego dostępu do niej.

Instrukcja 2 Laboratorium z Podstaw Inżynierii Oprogramowania

Aplikacje w środowisku Java

REFERAT PRACY DYPLOMOWEJ

Interfejsy i klasy wewnętrzne

Praca z kodem legacy : strategie, naprawa błędów, refaktoryzacja oraz

Refaktoryzacja. Na podstawie

Współbieżność w środowisku Java

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie Komputerów

Programowanie obiektowe. Wprowadzenie

Dziedziczenie. dr Jarosław Skaruz

Refaktoryzacja do wzorców projektowych

Weryfikacja i walidacja. Metody testowania systemów informatycznych

Programowanie w języku Java WYKŁAD

12) Wadą modelu kaskadowego jest: Zagadnienia obowiązujące na egzaminie z inżynierii oprogramowania: 13) Wadą modelu opartego na prototypowaniu jest:

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

METODY PROGRAMOWANIA

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Całościowe podejście do testowania automatycznego dla programistów. /C#/PHP (TDD, BDD, Spec. by Example, wzorce, narzędzia)

C# 6.0 : kompletny przewodnik dla praktyków / Mark Michaelis, Eric Lippert. Gliwice, cop Spis treści

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

Dziedziczenie. Streszczenie Celem wykładu jest omówienie tematyki dziedziczenia klas. Czas wykładu 45 minut.

Wzorce projektowe cz. II. Wzorce projektowe cz. II 1/35

Prototype (prototyp) Cel: Przykład: Określenie rodzaju tworzonych obiektów poprzez wskazanie ich prototypu. Nowe instancje tworzymy kopiując prototyp.

Testowanie II. Celem zajęć jest zapoznanie studentów z oceną jakości testów przy wykorzystaniu metryk pokrycia kodu testami (ang. code coverage).

Laboratorium 1. Wzorce oprogramowania lab1, Zofia Kruczkiewicz

Programowanie obiektowe

Co jeszcze mogą nam dać adnotacje? Adam Warski

Programowanie obiektowe

Programowanie obiektowe

Dziedziczenie. Tomasz Borzyszkowski

Wywoływanie metod zdalnych

Projektowanie obiektowe. Roman Simiński Wzorce projektowe Wybrane wzorce strukturalne

Programowanie obiektowe - 1.

Całościowe podejście do testowania automatycznego dla programistów. (TDD, BDD, Spec. by Example, wzorce, narzędzia)

Plik pobrano z Tytuł: Wzorce projektowe, cz. 2 Strategy Ostatnia aktualizacja:

Typy zmiennych proste i złożone. Programowanie komputerów. Tablica. Złożone typy zmiennych. Klasa. Struktura

Dokumentacja do API Javy.

Kurs programowania. Wykład 9. Wojciech Macyna

Java: interfejsy i klasy wewnętrzne

Dawid Gierszewski Adam Hanasko

MODELOWANIE OBIEKTOWE

Katalog przekształceń refaktoryzacyjnych cz. II

Projektowanie aplikacji internetowych laboratorium

Programowanie obiektowe i język Java

Enkapsulacja, dziedziczenie, polimorfizm

Techniki efektywnego testowania kodu dla programistów Java (Spock

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

Metody dostępu do danych

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

Program szkolenia: Test Driven Development (TDD) using Spock or JUnit 5

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

Programowanie obiektowe

Automatyczne generowanie kodu. 4Developers, 26 marca 2010

Programowanie obiektowe

Kurs WWW. Paweł Rajba.

Projektowanie obiektowe Wzorce projektowe

WYKORZYSTANIE JĘZYKA GROOVY W TESTACH JEDNOSTKOWYCH, INTEGRACYJNYCH I AUTOMATYCZNYCH. Mirosław Gołda, Programista Java

szkolenia pod drzewem Wybrane Techniki XP bnd 2008 Tomasz Włodarek. Materiał udostępniany na podstawie licencji Creative Commons (by-nc-nd) 1.00.

Zadanie polega na stworzeniu bazy danych w pamięci zapewniającej efektywny dostęp do danych baza osób.

Mechanizm dziedziczenia


Optimizing Programs with Intended Semantics

Wzorce projektowe. dr inż. Marcin Pietroo

Laboratorium z przedmiotu: Inżynieria Oprogramowania INEK Instrukcja 6

Programowanie obiektowe

Programowanie w Ruby

Wykład VII. Programowanie III - semestr III Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Wprowadzenie db4o - podstawy db4o - technikalia Przydatne wiadomości. Wprowadzenie. db4o. Norbert Potocki. 1 czerwca Norbert Potocki db4o

Scala - programowanie obiektowo-funkcyjne

Wprowadzenie do Behaviordriven

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

Transkrypt:

Etap implementacji Refaktoryzacja

Koncepcja refaktoryzacji Termin refaktoryzacja (ang. Refactoring) definiuje się jako mechanizm zmiany struktury kodu bez zmiany jego zachowania (funkcjonalności). Celem refaktoryzacji jest więc nie wytwarzanie nowej funkcjonalności, ale utrzymywanie odpowiedniej, wysokiej jakości organizacji systemu.

Przebieg procesu projektowego Funkcjonalność kodu Granica spełnienia zadanej funkcjonalności Automatyzacja niektórych czynności skraca czas modyfikacji kodu Okresy przeznaczane na refartoryzację Czas pracy nad kodem

Korzyści z refaktoryzacji Ułatwienie pielęgnacji (modyfikacji) kodu. Zwiększenie integralności danych i zgodności ich reprezentacji z semantyką języka. Ułatwienie wykorzystania mechanizmów automatycznego generowania kodu. Ograniczenie redundancji (nadmiarowości) i narzucanie standardów budowy. Zachowanie silnej separacji warstw systemu (w przypadku systemów o architekturze wielowarstwowej).

Dwukierunkowe działania w ramach refaktoryzacji Modyfikowanie elementów systemu w celu wpasowania ich w przyjęte standardy i wzorce. Poszukiwanie nowych standardów i wzorców, które pojawiają się w systemie w trakcie jego rozwoju i ich precyzyjne definiowanie.

Refaktoryzacja a zarządzanie projektem informatycznym. Przy dużych projektach koszt refaktoryzacji jest rekompensowany obniżką kosztów wprowadzenia późniejszych globalnych zmian w projekcie. W przypadku projektów obarczonych dużym ryzkiem niepowodzenia (np. z powodu niestabilnych wymagań funkcjonalnych klienta) regularnie prowadzona refaktoryzacja wydaje się nieodzowną.

Istota refaktoryzacji Przeprowadzać zmiany w sposób bezpieczny, to znaczy utrzymujący dotychczasową funkcjonalność zmienianego fragmentu programu. Dwie podstawowe metody weryfikacji poprawności przekształceń: analiza własności zmienianego kodu, testowanie jednostkowe wprowadzonych zmian.

Analiza własności zmienianego kodu Sprowadza się do wyznaczenia dla każdego przekształcenia refaktoryzacyjnego warunków wstępnych oraz końcowych, które muszą być spełnione, aby zmiana była poprawna. Warunki te to najczęściej statyczne własności klasy lub metody (np. jej relacje dziedziczenia, powiązania z innymi elementami systemu), dlatego ich weryfikacji w większości przypadków może dokonać kompilator lub analizator składniowy.

Testowanie jednostkowe Jest implementowane przy użyciu bibliotek z serii xunit, (np. JUnit). W istocie jest to regresyjna weryfikacja poprawności działania poszczególnych metod, czyli stwierdzenie, czy wprowadzane zmiany nie zmieniają zachowania klas. Testy stanowią niezmienniki przekształceń, bo muszą być spełnione zarówno przed, jak i po przeprowadzeniu zmian.

xunit rodziną narzędzi do testów modułowych Platforma xunit URL Java JUnit http://junit.org/ VBasic VBUnit http://www.vbunit.org C++ CPPUnit http://cppunit.sourceforge.net C# NUnit http://www.nunit.org Delphi DUnit http://dunit.sourceforge.net/ PHP PHPUnit http://www.phpunit.de/

Wolne narzędzia do refaktoryzacji Platform Tools URL General X-develop http://www.x-develop.com/ Delphi Model Maker http://modelmakertools.com/ Visual Basic C/C++ Java Refactor! for Visual Basic SlickEdit, Ref+ +, Xrefactory IntelliJ Idea, Eclipse, JFactor http://msdn.microsoft.com/vbasic/do wnloads/2005/tools/refactor/ http://www.slickedit.com/, http://www.ideatsolutions.com/refpp/, http://xreftech.com/xrefactory/main.html http://www.intellij.com/idea/, http://www.eclipse.org/, http://www.instantiations.com/jfactor

Refaktoryzacja a przykładowe IDE Typy refaktoryzacji dostępne w Eclipse: Na poziomie struktury fizycznej projektu (Physical Structure). Na poziomie struktury klas (Class Level Structure). Na poziomie wewnętrznej budowy klasy (Structure inside a Class).

Metody Physical Structure Rename Move Change Method Signature Convert Anonymous Class to Nested Convert Nested Type to Top Level (Eclipse 2) Move Member Type to New File (Eclipse 3)

Metody Class Level Structure Push Down Pull Up Extract Interface Generalize Type (Eclipse 3) User Supertype Where Possible

Metody Structure inside a Class Inline Extract Method Extract Local Variable Extract Constant Introduce Parameter (Eclipse 3 only) Introduce Factory (Eclipse 3 only) Encapsulate Field

Ocena jakości kodu Any fool can write code that a computer can understand. Good programmers write code that humans can understand. Przykry zapach jest symptomem niskiej jakości kodu, która wskazuje na konieczność refaktoryzacji. Martin Fowler Refactoring, Improving the design of existing code, Addison-Wesley, 1999

Zduplikowany kod (Duplicated Code) Objawy: ten sam lub podobny kod pojawia się w różnych miejscach systemu. Rozwiązania: Jedna klasa: wyłączenie wspólnych części do jednej metody (Extract Method). Bliźniacze klasy: wyłączenie metody ze wspólną funkcjonalnością i następnie podniesienie (Pull-up the Method) do wspólnej nadklasy. Niespokrewnione klasy: wyłączenie klasy (Extract Class) ze wspólnymi elementami i delegowanie do niej.

Duża metoda (Long Method) Objawy: Metoda wykonuje wiele różnych czynności. Brak wsparcia ze strony innych metod, przez co niektóre metody operują na niższym poziomie niż powinny. Nadmiernie skomplikowana obsługa wyjątków. Rozwiązania: Extract Method. Wyłączenie tymczasowych zmiennych do zewnętrznych metod (Replace Temp with Query). Zmniejszenie liczby parametrów (Introduce Parameter Object or Preserve Whole Object). Stworzenie nowej klasy z metody i podział funkcionalności (Replace Method with Method Object).

Duża klasa (Large class) Objawy: Klasa posiada zbyt duży zakres odpowiedzialności. Występują liczne klasy wewnętrzne i instancje klasy. Nadmierna liczba metod ułatwiających. Rozwiązania Ekstrakcja klasy w celu podziału klasy przez referencje. Ekstrakcja podklasy (Subclass) w celu podziału klasy przez dziedziczenie. Ekstrakcja interfejsu w celu podziału klasy przez polimorfizm. Przesunięcie części zadań do nadklasy (Superclass).

Leniwa klasa (Lazy Class) Objawy: klasa ma znikomą odpowiedzialność lub nie ma odpowiedzialności wcale. Rozwiązania: Wchłonięcie przez nadklasę/podklasę (Collapse Hierarchy). Wchłonięcie klasy przez referencje (Inline Class).

Klasa danych (Data Class) Objawy: klasa jest odpowiedzialna jedynie za przechowywanie danych i nie posiada istotnych metod (Transfer Object). Rozwiązania: Wzbogacenie funkcjonalności (Extract Method i Move Method). Usunięcie klasy (Inline Class).

Instrukcje przełączające (Switch Statements) Objawy: metoda posiada rozbudowany przepływ sterowania, oparty na złożonych wyrażeniach warunkowych. Rozwiązania: Wyłączenie wspólnych części do osobnych metod w tej samej klasie (Extract Method). Użycie polimorfizmu (Replace Conditional with Polymorphism/State). Użycie dziedziczenia (Replace Conditional with Subclasses).

Odrzucony spadek (Refused Bequest) Objawy: podklasy nie potrzebują odziedziczonych metod i pól. Rozwiązania: Utworzenie nowej klasy bliźniaczej (Push Down Method and Push Down Field). Zastąpienie dziedziczenia delegacją (Replace Inheritance with Delegation).

Niewłaściwa hermetyzacja (Inappropriate Intimacy) Objawy: bezpośredni dostęp do wewnętrznych pól innej klasy. Rozwiązania: Przesunięcie pól/metod do właściwej klasy (Move Method/ Move Field). Ograniczenie dwukierunkowych relacji (Change Bidirectional Association to Unidirectional Association). Wyłączenie elementów o wspólnym dostępie do osobnej klasy (Extract Class). Zastąpienie dziedziczenia delegacją.

Zazdrość o funkcję (Feature Envy) Objawy: Metoda jednej klasy intensywnie korzysta z funkcji innej klasy. Niska spójność klasy. Rozwiązania Przesunięcie metody do właściwej klasy (Move Method). Użycie wzorca Visitor.

Łańcuchy wywołań metod (Message Chains) Objawy: długie łańcuchy wywołań getanotherobject(). Rozwiązania: Ukrycie klas delegujących (Hide Delegate). Przesunięcie niektórych metod w dół łańcucha (Extract Method and Move Method).

Chirurgia śrutówką (Shotgun Surgery) Objawy: wprowadzona zmiana wymaga modyfikacji wielu innych klas. Rozwiązania: przesunięcie wszystkich obszarów zmienności do jednej klasy (Move Method and Move Field).

Przekształcenia refaktoryzacyjne Przykłady

Przykład: Rename Method class ClassA void Name_1 () { // some code class ClassA void Name_2 () { // some code Warunki wstępne: w klasie ClassA nie istnieje metoda void Name_2() klasa ClassA nie dziedziczy metod Name_1() ani Name_2() Warunki końcowe: klasa ClassA nie posiada metody Name_1() klasa ClassA posiada metodę Name_2()

Przykład: Extract Method void scalarproduct(string[] params) { int[] x = preparex(params); int[] y = preparey(params); int[] product = computexy(x, y); //... for (i = 0; i < x.length; i++) { out.println("x = " + x[i]); out.println("y = " + y[i]); out.println("x * Y = " + product[i]); void scalarproduct(string[] params) { int[] x = preparex(params); int[] y = preparey(params); int[] product = computexy(x, y); //... printscalarproduct(x, y, product); void printscalarproduct(int[] x, int[]y, int[] product) { for (i = 0; i < x.length; i++) { out.println("x = " + x[i]); out.println("y = " + y[i]); out.println("x * Y = " + product[i]); Warunki wstępne: wskazany blok modyfikuje co najwyżej jedną zmienną w klasie nie istnieje dotychczas metoda printscalarproduct() klasa nie dziedziczy metod scalarproduct() ani printscalarproduct()

Encapsulate Collection M. Fowler, 1999 Problem Metoda get() w klasie właściciela zwraca kolekcję dostępną do modyfikacji Cel Przeniesienie odpowiedzialności za kolekcję do jej właściciela Mechanika dodaj w klasie właściciela metody add() i remove() dla kolekcji, zmień bezpośrednie odwołania do metod add() i remove() kolekcji odwołaniami do metod jej właściciela, zmień metodę get() zwracającą kolekcję, tak aby zwracała jej widok tylko do odczytu, skompiluj i przetestuj, opcjonalnie: zmień metodę get() tak, aby zwracała Iterator.

Przykład public class Student { Collection wyklady; public Collection wyklady() { return wyklady; public class Student { Collection wyklady; public boolean dodajwyklad(wyklad w) { return wyklady.add(w); public boolean usunwyklad(wyklad w) { return wyklady.remove(w); public Collection wyklady() { return Collections.unmodifiableCollection(wyklady);

Wprowadź Null Object Problem Referencje do klasy wymagają ciągłego porównywania z wartością null Cel Wprowadzenie obiektu reprezentującego wartość null M. Fowler, 1999 Mechanika utwórz podklasę reprezentującą wartość null o nazwie NullKlasa, utwórz w klasie i podklasie metodę isnull(); w klasie metoda zwraca false, w podklasie true, skompiluj klasy, zastąp u klientów referencje null klasy instancjami podklasy, zastąp warunki sprawdzające referencję null wywołaniem isnull(), pokryj metody w podklasie zgodnie z semantyką obiektu reprezentującego null, usuń metody isnull().

Przykład public class Student { Collection wyklady; public Collection wyklady() { return wyklady; public class Student { Collection wyklady; public boolean dodajwyklad(wyklad w) { return wyklady.add(w); public boolean usunwyklad(wyklad w) { return wyklady.remove(w); public Collection wyklady() { return Collections.unmodifiableCollection(wyklady);

Przykład public class Student { Collection wyklady; public Collection wyklady() { return wyklady; public class Student { Collection wyklady; public boolean dodajwyklad(wyklad w) { return wyklady.add(w); public boolean usunwyklad(wyklad w) { return wyklady.remove(w); public Collection wyklady() { return Collections.unmodifiableCollection(wyklady);