Wzorce i refaktoryzacja w PHP
Template:Design Patterns Links
Design Patterns - Wzorce projektowe
Copyright Notice
Copyright © 2004-2023 by NobleProg Limited All rights reserved.
This publication is protected by copyright, and permission must be obtained from the publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form or by any means, electronic, mechanical, photocopying, recording, or likewise.
Kody źródłowe dla omawianych wzorców: http://svn.nobleprog.com/training/php/Patterns/
Podstawy ⌘
Próba zdefiniowania ⌘
Dlaczego patrząc na jakiś budynek jesteśmy w stanie określić wiek i styl architektoniczny w jakim powstał?
Charakterystyka ⌘
W danym wieku/epoce, projekty oparte były o obowiązujące wzorce
Definicja - ChristopherAlexander ⌘
Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.
Christopher Alexander
Co jest wzorcem? ⌘
Czy przypisanie do zmiennej, liczby elementów zmiennej tablicowej poza pętlą for, która po tej tablicy iteruje jest wzorcem?
Wzorzec kilograma ⌘
Silbermann Kilogram, historical secondary mass standard, National Institute of Standards and Technology Virtual Museum, http://museum.nist.gov
Co jest wzorcem? ⌘
for var = start_value to count(array) do
//...
endfor
end_value := count(array_value)
for var = start_value to end_value do
//...
endfor
Wzorce podlegają zmianom ⌘
Arnold Schönberg (1874-1951) - macierz 12-tonów, Music Theory Online, http://www.mtosmt.org/
Znane zmiany wzorców znane z architektury IT ⌘
Active Record a Domain Model?
Podsumowanie? ⌘
Pytanie: Czym są wzorce projektowe?
Systematyzacja ⌘
Próba systematyzacji: definicje i opracowanie przez Gang of Four (rok 1994): E. Gamma, R. Helm, R. Johnson, J. Vlissides
Definicja - Design Patterns Book ⌘
A design pattern systematically names, motivates, and explains a general design that addresses a recurring design problem in object-oriented systems. It describes the problem, the solution, when to apply the solution, and its consequences. It also gives implementation hints and examples. The solution is a general arrangement of objects and classes that solve the problem. The solution is customized and implemented to solve the problem in a particular context.
Design Patterns Book.
Inne wzorce ⌘
Pytanie: Jaka jest różnica pomiędzy wzorcami projektowymi, architektonicznymi, analitycznymi i implementacyjnymi?
Podział wzorców projektowych ⌘
- Kreacyjne
- Strukturalne
- Behawioralne
Podział wzorców projektowych - Kreacyjne ⌘
- Kreacyjne – Opisują sposoby tworzenia obiektów
- Strukturalne
- Behawioralne
Podział wzorców projektowych - Strukturalne ⌘
- Kreacyjne – Opisują sposoby tworzenia obiektów
- Strukturalne – Opisują sposoby tworzenia struktur obiektów
- Behawioralne
Podział wzorców projektowych - Behawioralne ⌘
- Kreacyjne – Opisują sposoby tworzenia obiektów
- Strukturalne – Opisują sposoby tworzenia struktur obiektów
- Behawioralne – Opisują sposoby oddziaływania i dzielenia się odpowiedzialnością pomiędzy obiektami
Elementy opisu wzorca projektowego ⌘
- Nazwa
- Problem
- Rozwiązanie
- Konsekwencje
Elementy opisu wzorca projektowego - Nazwa ⌘
- Nazwa: Singleton
- Problem
- Rozwiązanie
- Konsekwencje
Elementy opisu wzorca projektowego - Problem ⌘
- Nazwa: Strategia
- Problem: Uniemożliwienie stworzenia więcej niż jednej instancji obiektu
- Rozwiązanie
- Konsekwencje:
Elementy opisu wzorca projektowego - Rozwiązanie ⌘
- Nazwa: Strategia
- Problem: Uniemożliwienie stworzenia więcej niż jednej instancji obiektu
- Rozwiązanie
- Konsekwencje
Elementy opisu wzorca projektowego - Konsekwencje ⌘
- Nazwa: Strategia
- Problem: Uniemożliwienie stworzenia więcej niż jednej instancji obiektu
- Rozwiązanie
- Konsekwencje: Mogą wystąpić problemy z testowaniem, często nazywany eufemizmem dla zmiennej globalnej, brak możliwości utworzenia drugiej instancji (np. możliwość utworzenia połączenia do dodatkowej bazy danych)
Elementy wzorca projektowego – co jeszcze możemy opisać? ⌘
- Klasyfikacja
- Struktura
- Aliasy
- Przykład
- Podobne wzorce
Elementy wzorca projektowego – co jeszcze możemy opisać? - Klasyfikacja ⌘
- Klasyfikacja – kreacyjny, strukturalny, behawioralny?
- Struktura
- Aliasy
- Przykład
- Podobne wzorce
Elementy wzorca projektowego – co jeszcze możemy opisać? - Struktura ⌘
- Klasyfikacja – kreacyjny, strukturalny, behawioralny?
- Struktura – prezentacja na diagramie UML
- Aliasy
- Przykład
- Podobne wzorce
Elementy wzorca projektowego – co jeszcze możemy opisać? - Aliasy ⌘
- Klasyfikacja – kreacyjny, strukturalny, behawioralny?
- Struktura – prezentacja na diagramie UML
- Aliasy – Nazwy alternatywne (Singleton - Samotnik)
- Przykład
- Podobne wzorce
Elementy wzorca projektowego – co jeszcze możemy opisać? - Przykłady ⌘
- Klasyfikacja – kreacyjny, strukturalny, behawioralny?
- Struktura – prezentacja na diagramie UML
- Aliasy – Nazwy alternatywne (Singleton - Samotnik)
- Przykład – ilustrujący praktyczne wykorzystanie
- Podobne wzorce
Elementy wzorca projektowego – co jeszcze możemy opisać? - Podobne wzorce ⌘
- Klasyfikacja – kreacyjny, strukturalny, behawioralny?
- Struktura – prezentacja na diagramie UML
- Aliasy – Nazwy alternatywne (Singleton - Samotnik)
- Przykład – ilustrujący praktyczne wykorzystanie
- Podobne wzorce – wzorce stanowiące alternatywne rozwiązanie
Klasyfikacja ⌘
- Kreacyjne
- Strukturalne
- Behawioralne
Klasyfikacja - Kreacyjne ⌘
- Kreacyjne – Builder, Factory, Prototype, Singleton
- Strukturalne
- Behawioralne
Klasyfikacja - Strukturalne ⌘
- Kreacyjne – Builder, Factory, Prototype, Singleton
- Strukturalne – Delegate, Facade, Composite, Adapter, Decorator, Bridge, Proxy
- Behawioralne
Klasyfikacja - Behawioralne ⌘
- Kreacyjne – Builder, Factory, Prototype, Singleton
- Strukturalne – Delegate, Facade, Composite, Adapter, Decorator, Bridge, Proxy
- Behawioralne – Command, Template method, Chain of responsibility (Intercepting filter), Observer, Strategy, Iterator
Opinie ⌘
Opinie - Developers.com ⌘
First, they provide you with a way to solve issues related to software development using a proven solution. The solution facilitates the development of highly cohesive modules with minimal coupling. They isolate the variability that may exist in the system requirements, making the overall system easier to understand and maintain. Second, design patterns make communication between designers more efficient.
Developers.com
Opinie - stackexchange.com ⌘
KISS first, patterns later, maybe much later. A pattern is a state of mind, mostly. Don't ever try to force your code into a specific pattern, rather notice which patterns start to crystalise out of your code and help them along a bit.
stackexchange.com
Opinie - artima.com ⌘
That you can customize behavior without having to touch existing code—one of the classical OO themes. You can reuse something adapted to your particular problem.
artima.com
Quiz ⌘
Adres: http://www.gofpatterns.com/design-patterns/module2/why-use-design-patterns-quiz.php
Lub poszukaj frazy: "why use design patterns quiz"
Omówienie konkretnych wzorców ⌘
Singleton ⌘
Jedna instancja danej klasy np. jeśli tworzenie instancji wymaga zaangażowania dużych zasobów. Singleton jest również uważany za antywzorzec zaprzeczający założeniom programowania obiektowego. Alternatywą dla Singletona jest zastosowanie kontenerów wstrzykiwania zależności.
Zadanie "God Save the Queen"
Builder ⌘
Rozdzielenie procesu tworzenia obiektów od ich reprezentacji. Dzięki zastosowaniu Buildera, możliwa jest dekompozycja i delegowanie specjalistycznych zadań.
Factory ⌘
Automatyzacja i ułatwienie procesu tworzenia obiektów. Wzorzec z tej samej rodziny - Abstract Factory – to upraszczając fabryka fabryk.
Zadanie "Simple Mailer"
Prototype ⌘
Tworzenie obiektów na podstawie już istniejących (na podstawie prototypów). Zastosowanie tego wzorca pozwala na uniknięcie powtarzania kodu (DRY) oraz może zaoszczędzić zasoby – klonowanie wymaga mniej zasobów niż tworzenie nowej instancji.
Zadanie "Quick Object Persistence"
Delegate ⌘
Pozwala na przeniesienie niektóry funkcjonalności (delegowanie zadań) na rzecz innej klasy.
Facade ⌘
Agregacja zadań (które zazwyczaj wykonywane są razem) różnych klas do jednej klasy – fasady.
Zadanie "Simple Mailer"
Composite ⌘
Wzorzec przeznaczony do pracy z danymi ujętymi w strukturze drzewiastej. Jego zadamniem jest ujednolicenie intrefejsu pomiędzy liśćmi a kompozytami.
Zadanie "Empleyee Hierarchy"
Adapter ⌘
Różnice interfejsów między systemem a zewnętrzną biblioteka. Zastosowanie tego wzorca ułatwia integrację bibliotek zewnętrznych które posiadają inny interfejs niż system.
Zadanie "French Code Legacy"
Decorator ⌘
Umożliwia wzbogacenie funkcjonalności danej klasy. Czemu więc nie zastosować dziedziczenia? Dodatkowe funkcjonalności nie są związane z przeznaczeniem dekorowanej klasy.
Zadanie "Dummy Registration"
Bridge ⌘
Konieczność odseparowania abstrakcji od implementacji. Pozwala na uniknięcie eksplozji kombinacji m*n.
Proxy ⌘
Ułatwia pracę ze zdalnymi obiektami, oraz pozwala na odłożenie w czasie tworzenia obiektu wymagającego zaangażowania dużej ilości zasobów (CPU, RAM, etc.)
Zadanie "Rocket Post Manager"
Command ⌘
Pozwala na enkapsulację zadań, parametryzowanie ich a dalej na ich kolejkowanie i anulowanie. Pozwala na wykonanie pewnych zadań atomowo.
Zadanie "Profile Image Manager"
Template Method ⌘
Pozwala na separację implementacji od abstrakcji. Abstrakcja definiuje szablon algorytmu a implementacje dotyczą tylko poszczególnych jego kroków.
Chain Of Responsibility ⌘
Pozwala na utworzenie kolejki (łańcucha) pewnych zadań. Ponadto, w przypadku kiedy jedno z ogniw nie może obsłużyć żądania przekazuje je do zdefiniowanego, kolejnego ogniwa. Odmianą tego wzorca jest Intercepting Filters (Przechwytywane filtry) dzięki którym można usystematyzować pewne grupy, często wykonywanych zadań.
Zadanie "Simple Mailer", "Spam Protection"
Observer ⌘
Pozwala na dodanie dodatkowej funkcjonalności do istniejących klas. Umożliwia tworzenie architektury opartej o zdarzenia (EOA). Dodanie nowej funkcjonalności (tu tożsame z reakcją na zdarzenie) nie wymaga modyfikacji istniejącego kodu, zmian konfiguracyjnych czy tworzenia klas pochodnych.
Strategy ⌘
Umożliwia wybór i manipulację strategiami wykonywania danej czynności. Separuję konkretną strategię od klienta. Uwaga! Niejednokrotnie przykłady opisujące wzorzec Stategy i Factory są pozornie podobne. Factory pozwala na parametryzację tworzenia konkretnych instancji podczas gdy Strategy na parametryzację pewnych zadań.
Iterator ⌘
Pozwala na dostęp do elementu znajdujcego się w kolekcji obiektów.
Zadanie "Empleyee Hierarchy"
Kody źródłowe dla omawianych wzorców: http://svn.nobleprog.com/training/php/Refactoring/
Czym jest refaktoryzacja? ⌘
Definicja ⌘
Zmiany kodu niewpływające na jego funkcjonalność.
Definicja - Martin Fowler ⌘
Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.
Martin Fowler
Czemu ma służyć? ⌘
Jakiego efektu spodziewamy się po refaktoryzacji?
- Efekty mierzalne w krótkim czasie
Czemu ma służyć? ⌘
Jakiego efektu spodziewamy się po refaktoryzacji?
- Efekty mierzalne w krótkim czasie
- Efekty mierzalne w długim czasie
Koszt refaktoryzacji ⌘
Estymujmy wykres funkcji trzech zmiennych:
- Koszt
- Czas
- Jakość
dla:
- Systemu, którego kod poddany jest refaktoryzacji po jego uruchomieniu
Koszt refaktoryzacji ⌘
Estymujmy wykres funkcji trzech zmiennych:
- Koszt
- Czas
- Jakość
dla:
- Systemu, którego kod poddany jest refaktoryzacji po jego uruchomieniu
- Systemu, który zostaje stworzony od nowa
Kiedy kod podlega refaktoryzacji? ⌘
Refaktoryzacja jest procesem ciągłym. Podczas refaktoryzacji nie zmienia się funkcjonalność kodu ale poprawia się jego jakość. Estymujmy wykres funkcji, która odzwierciedla zmiany funkcjonalności względem czasu.
Refaktoryzacja a TDD ⌘
Zgodnie z założeniami TDD, następuje po stworzeniu kodu realizującego funkcjonalności "opisane" przez testy jednostkowe. Patrząc na system z perspektywy cyklu życia oprogramowania, refaktoryzacja występuje na etapach rozwoju oraz utrzymaniu (pielęgnacji systemu). Poniżej opisujemy kroki wytwarzania produktu zgodnie z TDD:
- Utworzenie testów jednostkowych na podstawie wymagań użytkownika końcowego (klient, biznes, Product Owner etc.)
- Stworzenie kodu, którego zadaniem jest spełnienie funkcjonalności opisanej przez testy. Na tym etapie kod realizuje zakładane funkcjonalności jednak jest niskiej jakości i trudny do dalszego rozwoju.
- Refaktoryzacja utworzonego kodu.
Cykl ilustruje schemat: [1]
Refaktoryzacja a DDD ⌘
Na "wyższym" poziomie, jednym ze wzorców refaktoryzacji jest przejście z kodu proceduralnego na obiektowy. Tutaj konieczne jest zwrócenię uwagi na model dziedziny (ang. Domain Model):
An object model of the domain that incorporates both behavior and data.
At its worst business logic can be very complex. Rules and logic describe many different cases and slants of behavior, and it's this complexity that objects were designed to work with. A Domain Model creates a web of interconnected objects, where each object represents some meaningful individual, whether as large as a corporation or as small as a single line on an order form.
Martin Fowler
Refaktoryzacja a zasada KISS ⌘
KISS - Mając wiedzę na temat wzorców projektowych i wzorców refaktoryzacji możliwe jest uproszczenie kodu systemu.
Refaktoryzacja a zasada DRY ⌘
DRY - Podobnie jak wyżej, dzięki odpowiedniej wiedzy jesteśmy w stanie zredukować nie tylko powtarzające się linie kodu ale też powtarzające się funkcjonalności realizowane przez różne klasy.
Refaktoryzacja a jakość ⌘
W zależności od przyjętych kryteriów, jakość kodu jest jednym ze składników ogólnie przyjętych norm jakości produktu. Jakość jest jednym z najważniejszych czynników związanych z procesem tworzenia oprogramowania. Aby zrozumieć znaczenie jakości warto zaznaczyć, że np. zarówno w metodyce PRINCE2 (jeden z Tematów) jak i Scrum (chociażby Code reviews) zajmuje istotne miejsce.
Code smell ⌘
A code smell is a hint that something has gone wrong somewhere in your code.
Wnioski - Korzyści ⌘
- Ułatwienie procesu pielęgnacji i dalszego rozwoju systemu
Wnioski - Korzyści ⌘
- Ułatwienie procesu pielęgnacji i dalszego rozwoju systemu
- Zapobieganie redundancji kodu
Wnioski - Korzyści ⌘
- Ułatwienie procesu pielęgnacji i dalszego rozwoju systemu
- Zapobieganie redundancji kodu
- Ułatwienie podczas dokumentowania systemu
Wnioski - Korzyści ⌘
- Ułatwienie procesu pielęgnacji i dalszego rozwoju systemu
- Zapobieganie redundancji kodu
- Ułatwienie możliwości dokumentowania systemu
- Tworzenie kodu zgodnie z przyjętymi standardami, co ułatwia jego zrozumienie
Wnioski - Korzyści ⌘
- Ułatwienie procesu pielęgnacji i dalszego rozwoju systemu
- Zapobieganie redundancji kodu
- Ułatwienie możliwości dokumentowania systemu
- Tworzenie kodu zgodnie z przyjętymi standardami co ułatwia jego zrozumienie
- Ułatwienie w utrzymaniu (zachowaniu) odpowiednich warstw systemu
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
- Niezrozumienie wymagań klienta
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
- Niezrozumienie wymagań klienta
- Brak kompetentnego zespołu
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
- Niezrozumienie wymagań klienta
- Brak kompetentnego zespołu
- Brak kompetentnego kierownika projektu (ale też czasami - używając nomenklatury metodyki PRINCE2 - komitetu sterującego a nawet organizacji jeśli mówimy o mikroprzedsiębiorstwach)
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
- Niezrozumienie wymagań klienta
- Brak kompetentnego zespołu
- Brak kompetentnego kierownika projektu (ale też czasami - używając nomenklatury metodyki PRINCE2 - komitetu sterującego a nawet organizacji jeśli mówimy o mikroprzedsiębiorstwach)
- Brak systematyczności - niekiedy koszt przepisania systemu jest niższy niż jego refaktoryzacji
Na jakie problemy refaktoryzacja nie jest rozwiązaniem ⌘
- Zła architektura systemu
- Niezrozumienie wymagań klienta
- Brak kompetentnego zespołu
- Brak kompetentnego kierownika projektu (ale też czasami - używając nomenklatury metodyki PRINCE2 - komitetu sterującego a nawet organizacji jeśli mówimy o mikroprzedsiębiorstwach)
- Brak systematyczności - niekiedy koszt przepisania systemu jest niższy niż jego refaktoryzacji
- Nieprawidłowy wybór technologii
Template:Design Patterns Links
Kody źródłowe dla omawianych wzorców: http://svn.nobleprog.com/training/php/Refactoring/
Add parameter ⌘
Parametryzacja metody, pozwala na uniknięcie konieczności jej późniejszych zmian.
Change Bidirectional Association to Unidirectional ⌘
Istnieje dwustronna relacja pomiędzy obiektami, ale jeden z nich nie potrzebuje dostępu do funkcjonalności drugiego.
Change Reference to Value ⌘
Odwrócenie wzorca "Change Value to Reference".
Change Unidirectional Association to Bidirectional ⌘
Wzorzec odwrotny do "Change Bidirectional Association to Unidirectional"
Change Value to Reference ⌘
Istnieje klasa z wieloma, takimi samymi instancjami, które należy zamienić w pojedynczy obiekt. Należy zamienić obiekt (wartość) na referencję. Dzięki temu rozwiązaniu możemy w klasie korzystać z obiektów zewnętrznych.
Collapse Hierarchy ⌘
Klasa rodzica i dziecka nie różnią się znacząco od siebie. Należy połączyć klasy ze sobą. TODO: Source
Consolidate Conditional Expression ⌘
Kilka warunków sprawdza jeden rezultat. Należy je skonsolidować. TODO: Source
Consolidate Duplicate Conditional Fragments ⌘
Niezależnie od warunku wykonywane są te same czynności. Należy je przenieść poza warunek. TODO: Source
Decompose Conditional ⌘
Instrukcje warunkowe są skomplikowane. Należy zastosować dekompozycje warunków. TODO: Source
Encapsulate Collection ⌘
TODO: Source
Encapsulate Collection ⌘
Metoda zwraca kolekcję. Należy zwracać kolekcję bez możliwości jej modyfikacji (w trybie do odczytu) oraz udostępnić metody pozwalające na dodawanie i usuwanie elementów z kolekcji. TODO: Source
Encapsulate Downcast ⌘
Metoda powinna zwracać wartość obiektu rzutowanego w dół a nie zbytnie uogólnionego.
Encapsulate Field ⌘
Istnieją publiczne pola klasy. Należy zastąpić je akcesorami i ustawić jako prywatne.
Extract Class ⌘
Rozdzielenie funkcjonalności zdefiniowanej w klasie na dwie niezależne.
Extract Method ⌘
Zebranie podobnych funkcjonalności i przeniesienie ich do odpowiedniej metody.
Hide Delegate ⌘
Ukrycie przed klientem niektórych szczegółów delegowanego obiektu (zgodnie z paradygmatem enkapsulacji).
Hide Method ⌘
Metoda nie jest używana przez klienta bądź inne klasy - należy ją ukryć.
Inline Class ⌘
Scalenie funkcjonalności klas, które mają podobną funkcjonalność (np. operują na tym samym obiekcie biznesowym) .
Inline Method ⌘
Nazwa metody odzwierciedla jej działanie (jest ponadto czytelna) i nie ma konieczności dekompozycji tej funkcji. Należy scalić metody.
Inline Temp ⌘
Wynik działania metody jest przypisywany do tymczasowej zmiennej. W takiej sytuacji należy unikać tworzenia zmiennych tymczasowych.
Introduce Explaining Variable ⌘
Należy stworzyć zmienną, której nazwa odzwierciedla jej działanie.
Introduce Foreign Method ⌘
Rozszerzenie klasy klienta o metodę, która powinna być dostępna w klasie serwera, ale klasy tej nie możemy modyfikować.
Introduce Local Extension ⌘
Konieczne jest rozszerzenie funkcjonalności klasy, której nie możemy modyfikować (dziedziczenie lub wzorzec Dekorator).
Introduce Null Object ⌘
Istnieje konieczność sprawdzania czy dany obiekt (lub jego metoda) nie jest pusty (NULL). W przypadku wielokrotnej konieczności sprawdzenia tego warunku, należy wprowadzić pusty obiekt dzięki czemu można uniknąć wielokrotnego porównywania do wartości NULL oraz podejmowania różnych działań jeśli warunek okaże się prawdziwy.
Introduce Parameter Object ⌘
Metoda przyjmuje parametry, które potrzebne są do wykonania jednej operacji. Zamiast przekazywania dwóch parametrów należy je scalić w jeden.
Move Field ⌘
Przeniesienie pola/właściwości do klasy, która częściej będzie je/ją wykorzystywać.
Move Method ⌘
Analogicznie do Move Field.
Parameterize Method ⌘
Istnieją metody realizujące bardzo podobne zadania. Należy zamienić je na jedną z odpowiednimi parametrami.
Pull Up Constructor Body ⌘
Konstruktory klas dziedziczących mają taką samą funkcjonalność. Należy przenieść konstruktor do klasy rodzica.
Pull Up Field ⌘
Analogicznie do "Pull Up Constructor Body".
Pull Up Method ⌘
Analogicznie do Pull Up Field.
Push Down Field ⌘
Odwrócenie wzorca "Pull Up Field".
Push Down Method ⌘
Odwrócenie wzorca "Pull Up Method".
Remove Assignments to Parameters ⌘
W ramach działania jakiegoś algorytmu nadpisywana jest wartość (również typ) zmiennej. W takiej sytuacji, w celu łatwiejszej analizy kodu należy wprowadzić dodatkowe zmienne.
Remove Control Flag ⌘
Istnieje zmienna pełniąca rolę flagi i zmieniająca się w zależności od różnych warunków. Należy używać konstrukcji breake lub return zamiast tej zmiennej.
Remove Double Negative ⌘
W warunku występuje podwójna negacja (~~). Należy zastąpić warunek przyrównaniem do prawdy.
Remove Middle Man ⌘
Odwrócenie wzorca "Hide Delegate".
Remove Parameter ⌘
Parametr nie jest używane przez metodę. Należy go usunąć.
Remove Setting Method ⌘
Istnieje metoda, która pozwala na modyfikację danych, które nie powinny być modyfikowane. Dane te należy przekazywać za pomocą konstruktora a metodę usunąć.
Rename Method ⌘
Nazwa metody nie oddaje jej działania. Należy zmienić nazwę metody.
Replace Array with Object ⌘
Istnieje tablica przechowująca wiele różnych wartości (również co do typu). Należy zastąpić tablicę obiektem.
Replace Conditional with Polymorphism ⌘
Istnieje warunek który podejmuje różne działania w zależności od typu obiektu. Należy utworzy klasy dziedziczące i skorzystać z polimorfizmu.
Replace Conditional with Visitor ⌘
TODO
Replace Constructor with Factory Method ⌘
Przeznaczenie konstruktora jest niewystarczające. Należy zastąpić tworzenie obiektu metodą fabrykującą zamiast za pomocą konstruktora.
Replace Data Value with Object ⌘
Istnieje zmienna/pole które potrzebuje dodatkowych funkcjonalności bądź właściwości. Należy zamienić tą zmienną/pole obiektem.
Replace Delegation with Inheritance ⌘
Należy, jeśli to możliwe, zastąpić delegację dziedziczeniem.
Replace Error Code with Exception ⌘
System korzysta z wewnętrznego mechanizmu zgłaszania błędów (np. oznacza błędy symbolami). Należy zastąpić je wyjątkami.
Replace Magic Number with Symbolic Constant ⌘
Należy przenieść stałe wartości do odpowiednich zmiennych.
Replace Parameter with Explicit Methods ⌘
Istnieje jeden akcesor (lub metoda wykonująca różne działania w zależności od parametru) dla wielu zmiennych. Należy zastąpić go osobnymi akcesorami dla każdej ze zmiennych.
Replace Recursion with Iteration ⌘
Algorytm korzysta z rekurencji. Należy zastąpić rekurencję pętlą jeśli to możliwe.
Replace Subclass with Fields ⌘
Klasy dziedziczące różnią się tylko zmienną. Należy ją przenieść do klasy rodzica.
Replace Temp with Query ⌘
Zmienne tymczasowe przechowują rezultat jakiegoś wyliczenia. W takiej sytuacji, wyliczenie to można przenieść do metody, istnieje bowiem możliwość jej wielokrotnego użycia.
Replace Type Code with State/Strategy ⌘
W zależności od typu (stałej) zmienia się zachowanie obiektu. Nie jest możliwe zastosowanie dziedziczenia i polimorfizmu. Należy użyć wzorca Strategii lub Stanu.
Reverse Conditional ⌘
Należy zmodyfikować wyrażenie warunkowe jeżeli odwrócenie warunków będzie bardziej zrozumiałe.
Separate Query from Modifier ⌘
Metoda jednocześnie pobiera jak i modyfikuje wartości. Należy rozdzielić ją na dwie metody: odpowiednio modyfikującą i pobierającą.
Split Loop ⌘
Podczas przebiegu pętli wykonywanych jest zbyt wiele czynności. Należy rozdzielić pętlę na kilka niezależnych.
Split Temporary Variable ⌘
Do jednej zmienne tymczasowej przypisywane są wyniki działania różnych wyliczeń. Należy utworzyć osobne zmienne dla każdego z wyliczeń wraz z odpowiednią nazwą. Ten wzorzec nie dotyczy zmiennych tymczasowych nadpisywanych w pętlach.
Substitute Algorithm ⌘
Dany algorytm możliwy jest do zrealizowania w prostszy sposób. Należy zastąpić bardziej skomplikowany prostszym.
Separate Domain from Presentation ⌘
Wzorzec mówi o separacji domeny (dziedziny) od prezentacji. Przykładem może być realizacja aplikacji zgodnie ze wzorce MVC/MVP/MVVM.
Convert Procedural Design to Objects ⌘
W przypadku wielu systemów (pomijamy tak specyficzne rozwiązania jak programy pisane np. w Prologu gdzie obiekt ma inne znaczenie niż w ogólnie przyjętym rozumieniu wywodzącym się z OOP) programowanie obiektowe wydaje się najlepszym rozwiązaniem. Część z języków traktuje wszystko jako obiekt. Ze wzorcem tym wiąże się pojęcie "Primitive Obsession", czyli unikanie typów prostych (w szczególności dla obiektów dziedziny). W językach wspierających programowanie proceduralne, funkcyjne i obiektowe znaczenie "Primitive Obsession" może być szczególnie istotne przez wzgląd na "praktyki" programistów.
Kody źródłowe dla omawianych wzorców: http://svn.nobleprog.com/training/php/Refactoring/
PHP Code Sniffer ⌘
Czym jest PHP Code Sniffer? ⌘
Narzędzie sprawdzające składnię (nie pod kątem poprawności) kodu pod kątem konwencji kodowania (Codding Standards) jak na przykład: niepotrzebnych białych znaków, konwencji nazewnictwa zmiennych, klas, metod etc.
Instalacja ⌘
pear install PHP_CodeSniffer
Wyświetlanie listy zainstalowanych standardów ⌘
phpcs -i
Sprawdzanie składni wybranej klasy ⌘
phpcs --standard=Zend Customer.php
PHP Coding Standards Fixer ⌘
Czym jest PHP Coding Standards Fixer? ⌘
Narzędzie poprawiające składnie kodu pod kątem konwencji kodowania (Codding Standards). Twórcami narzędzia jest firma Sensio Labs, stojąca za frameworkiem Symfony.
Instalacja ⌘
sudo wget http://cs.sensiolabs.org/get/php-cs-fixer.phar -O <sciezka_instalacji>/php-cs-fixer
Poprawienie składni wybranej klasy ⌘
php php-cs-fixer.phar fix Customer.php --fixers=linefeed,short_tag,indentation
PHPLOC ⌘
Czym jest PHPLOC? ⌘
Narzędzie analizy struktury (jak liczba linii kodu, liczby metod, klas etc) autorstwa Sebastiana Bergmanna.
Instalacja ⌘
pear config-set auto_discover 1
pear install pear.phpunit.de/phploc
Analiza kodu ⌘
phploc Customer.php
PHP Copy/Paste Detector (PHPCPD) ⌘
Czym jest PHP Copy/Paste Detector (PHPCPD)? ⌘
Narzędzie pozwalające na odnalezienie zduplikowanych (minimalna liczba wykrywanych linii możliwa jest do skonfigurowania) linii kodu. Zduplikowane funkcjonalności można zastąpić jedną metodą. Autorem narzędzia jest Sebastian Bergmann.
Instalacja ⌘
pear config-set auto_discover 1
pear install pear.phpunit.de/phpcpd
Przeszukiwanie kodu pod kątem zduplikowanych linii kodu ⌘
phpcpd <sciezka_projektu>
Dead Code Detector ⌘
Czym jest Dead Code Detector? ⌘
Narzędzie pozwalające na odnalezienie zadeklarowanych metod i zmiennych, które nie są używane, autorstwa Sebastiana Bergmanna.
Instalacja ⌘
pear config-set auto_discover 1
pear install pear.phpunit.de/phpdcd
Przeszukiwanie kodu pod kątem nieużywanych zmiennych i metod ⌘
phpdcd <sciezka_projektu>
PHP Depend ⌘
Czym jest PHP Depend? ⌘
Narzędzie pozwalające na analizę metryk oprogramowania.
Instalacja ⌘
pear channel-discover pear.pdepend.org
pear install pdepend/PHP_Depend-beta
Analiza metryk kodu ⌘
phpdepend <sciezka_projektu>
w wersji 1.1.4:
pdepend <sciezka_projektu>
PHPMD - PHP Mess Detector ⌘
Czym jest PHPMD - PHP Mess Detector? ⌘
Narzędzie pozwalające na analizę wielu aspektów związanych z oprogramowaniem takimi jak na przykład: złożoność cyklomatyczną, nadmierną złożoność metod, nadmierną wielkość klas, użycie zmiennych globalnych, konwencje nazewnicze, użycia niezalecanych konstrukcji jak eval czy GOTO, nieużywanych metod etc.
Instalacja ⌘
pear channel-discover pear.phpmd.org
pear channel-discover pear.pdepend.org
pear install --alldeps phpmd/PHP_PMD
Analiza kodu ⌘
phpmd <sciezka_projektu> xml codesize