Oprogramowanie można podzielić na typu według wielu rożnych
kluczy, jednym z nich może być: czy buduje produkt który będę utrzymywał przez lata, czy piszę kod dla kogoś - i przyszłość rozwiązania to nie będzie już moje zmartwienie. Przy tak postawionym pytaniu zasadnicza różnica dotyczy jakości, nie tylko ostatecznego produktu (działa czy nie działa) ale jakości samego rozwiązania. Nie tego co zostało dostarczone ale jak zostało zrobione. Bo właśnie to 'jak' wpływa później na koszt nanoszenia poprawek, dodawania kolejnych elementów, poprawiania ewentualnych błędów. Na wykładzie chciałbym przybliżyć te zasady jak, jak programować aby później z trwoga nie wracać do fragmentów sprzed lat. Jakich trzymać się zasad aby kod był czytelny, klarowny, intencja jasna a całość była dobrze zaprojektowana
4Developers 2018: Unit testing - introduction (Marek Kawczyński)PROIDEA
This short presentation is for people who would like to start with writing unit tests. I will try to introduce idea and definition of unit testing. With simple examples, we will go through the whole unit testing development process. Unit test, mocks, stubs, TDD and more definitions will be explained in real cases.
I will try to show how and what should be tested. Of course, everything is based on my personal experience that I have gained in my developer life in the last 10+ years.
“Revert” to ostatnia faza rozpaczliwego kodowania pomysłu, który na początku wydawał się najgenialniejszym kawałkiem kodu, jaki kiedykolwiek powstał. Po zakończeniu mojej prezentacji z kilkoma konkretnymi technikami, które pomogą Ci “dokodować” swoje pomysły do końca. Przyjrzymy się między innymi: wyodrębnianiu i dekomponowaniu zadań programistycznych, planowaniu pracy, poszukiwaniu błędów w kodzie i umiejętności skupienia się.
Oprogramowanie można podzielić na typu według wielu rożnych
kluczy, jednym z nich może być: czy buduje produkt który będę utrzymywał przez lata, czy piszę kod dla kogoś - i przyszłość rozwiązania to nie będzie już moje zmartwienie. Przy tak postawionym pytaniu zasadnicza różnica dotyczy jakości, nie tylko ostatecznego produktu (działa czy nie działa) ale jakości samego rozwiązania. Nie tego co zostało dostarczone ale jak zostało zrobione. Bo właśnie to 'jak' wpływa później na koszt nanoszenia poprawek, dodawania kolejnych elementów, poprawiania ewentualnych błędów. Na wykładzie chciałbym przybliżyć te zasady jak, jak programować aby później z trwoga nie wracać do fragmentów sprzed lat. Jakich trzymać się zasad aby kod był czytelny, klarowny, intencja jasna a całość była dobrze zaprojektowana
4Developers 2018: Unit testing - introduction (Marek Kawczyński)PROIDEA
This short presentation is for people who would like to start with writing unit tests. I will try to introduce idea and definition of unit testing. With simple examples, we will go through the whole unit testing development process. Unit test, mocks, stubs, TDD and more definitions will be explained in real cases.
I will try to show how and what should be tested. Of course, everything is based on my personal experience that I have gained in my developer life in the last 10+ years.
“Revert” to ostatnia faza rozpaczliwego kodowania pomysłu, który na początku wydawał się najgenialniejszym kawałkiem kodu, jaki kiedykolwiek powstał. Po zakończeniu mojej prezentacji z kilkoma konkretnymi technikami, które pomogą Ci “dokodować” swoje pomysły do końca. Przyjrzymy się między innymi: wyodrębnianiu i dekomponowaniu zadań programistycznych, planowaniu pracy, poszukiwaniu błędów w kodzie i umiejętności skupienia się.
Jak zacząć, aby nie żałować - czyli 50 twarzy PHPPiotr Horzycki
Prezentacja na phpCE Polska 2017. Omawiam historię PHP oraz sposób, w jaki wykorzystujemy go dzisiaj. Pokazuję, w jaki sposób wybierać narzędzia i architekturę, aby nasze projekty żyły na produkcji długo i szczęśliwie.
Od codziennej higieny do strategicznej refaktoryzacjiMichał Bartyzel
• W jaki sposób już teraz możesz upiększyć swój kod?
• Jak refaktoryzować bez konieczności ukrywania tego w szacowaniach?
• Jak w ciągu 30 minut wyprostować najbardziej zagmatwany algorytm?
• W jaki sposób planować duże strategiczne refaktoryzacje?
• Jak w uporządkowany sposób przeprowadzać długotrwałe refaktoryzacje?
• Jak uniknąć niespójnej architektury w trakcie długotrwałej refaktoryzacji?
• Jak negocjować czas na refaktoryzację z Twoim managerem, PO czy klientem?
JDD 2016 - Wojciech Oczkowski - Testowanie Wydajnosci Za Pomoca Narzedzia JMHPROIDEA
W prezentacji pokażę jak wykorzystać narzędzie JMH do budowy microbenchmarków testujących wydajność zadanych kawałków kodu. Nabyte umiejętności pozwolą słuchaczom sprawdzić wydajność wybranych fragmentów kodu bez niebezpieczeństwa popełnienia, typowych dla tego typu testowania, błędów związanych z np. wygrzewaniem maszyny wirtualnej czy działalnością garbage collectora.
Techniki, czyli przekształcenia refaktoryzacyjne pomagają transformować fragmenty kodu z jednej postaci w inną. Jednak duże refaktoryzacje to przede wszystkim przedsięwzięcie organizacyjne. Co warto refaktoryzować? Jak zidentyfikować kluczowe problemy? Kiedy nie podejmować działań? Czy w ogóle warto? Jakie heurystyki i strategie wysokopoziomowe możesz wykorzystać? Odpowiedzi na te pytania poznasz podczas prelekcji Strategiczna refaktoryzacja.
GameDev od zaplecza
Nie samymi grami gamedev żyje. Z czasem, pojawiają się potrzeby dodania kolejnych klocków, wspólnych dla wszystkich gier, i nie koniecznie związanych z samym gameplayem. Zaczynamy przechodzić na ciemną stronę backendu tworząc serwisy rozszerzające naszą grę o, często niewidoczne dla graczy, ale istotne z punktu widzenia marketingu i analityki ficzery. Na przykładzie jednego z naszych serwisów pokażemy wam jakich technologii używamy w pracy, aby zapewnić stabilne działanie całej siatki ponad 200 mikroserwisów!
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...PROIDEA
Michał Charmas
Language: Polish
Pisanie dobrego oprogramowania na platformę Android jest trudnym zadaniem.
Jednym z dużych problemów, zwłaszcza w przypadku sporych aplikacji, może być podział
logiki aplikacji tak, aby nasze Activity czy Fragmenty nie były nią przeładowane
oraz aplikacja była podatna na testowanie jednostkowe. Szukając pomysłu na
architekturę aplikacji, która będzie dobrze się skalowała wraz z rozwojem projektu,
natknąłem się na Clean Architecture zaproponowaną przez Boba C. Martina.
Podczas prezentacji zobaczymy czy i jak CA sprawdza się w przypadku
aplikacji mobilnych na Androida i na co pozwala jej zastosowanie. Oczywiście nie pominiemy
takich kluczowych kwestii jak pogodzenie tego wszystkiego z wszechobecną na Androidzie
asynchronicznością.
Wbrew powszechnym opiniom, nie tak prosto jest zrobić dobre Code Review. Robione w pośpiechu, tylko po to by je "odbębnić", często stwarza więcej szkody niż pożytku. Opowiem wam dlaczego code review jest ważne i jak wykorzystać ten proces aby upewnić się, że napisany kod jest najwyższej jakości. Będę nie tylko mówił o tym kto powinien robić code reviews, i dla kogo, jakie informacje są potrzebne do przeprowadzenia skutecznego code review, ale także jak zrobić dobre code review w najkrótszym możliwym czasie.
JDD2014: Strategiczna refaktoryzacja - Michał BartyzelPROIDEA
Techniki, czyli przekształcenia refaktoryzacyjne pomagają transformować fragmenty kodu z jednej postaci w inną. Jednak duże refaktoryzacje to przede wszystkim przedsięwzięcie organizacyjne. Co warto refaktoryzować? Jak zidentyfikować kluczowe problemy? Kiedy nie podejmować działań? Czy w ogóle warto? Jakie heurystyki i strategie wysokopoziomowe możesz wykorzystać? Odpowiedzi na te pytania poznasz podczas prelekcji Strategiczna refaktoryzacja.
Przez kilkanaście lat pracy zawodowej wielokrotnie padłem ofiarą mitów i przejściowych trendów przemysłu IT. Bałem się wysłać CV na widok ściany wymagań. Wprowadzałem Scruma "na siłę", przepisywałem systemy od zera, budowałem wymyślną architekturę. Umknęło mi wiele ważnych rzeczy, na które dziś pragnę zwrócić Waszą uwagę. Opowiem jak możecie ruszyć swoją karierę "z kopyta" poprzez skupienie się na 20% rzeczy, które dadzą 80% rezultatów. Pokażę, jakie praktyki realnie pozwoliły mi osiągać duże sukcesy u klientów z całego świata.
"Pitfalls of Object-Oriented Programming" [Polish] Prezentacja do wykładu przygotowanego na Koło Naukowe Twórców Gier "Polygon" na Politechnice Warszawskiej, a w drugiej wersji wygłoszonego także na AGH w Krakowie.
Opracowana na podstawie tekstu Fanatyzm obiektowy, przedstawia krytyczne podejście do projektowania i programowania obiektowego (m.in. pisania wrapperów na używane biblioteki, nadmiernej generalizacji, nadużywania dziedziczenia, enkapsulacji, wzorców projektowych) oraz jego negatywny wpływ na prostotę i czytelność kodu. Jako alternatywę prezentuje podejście DOD (Data-Oriented Design).
Published 2011-03-30
Jak zacząć, aby nie żałować - czyli 50 twarzy PHPPiotr Horzycki
Prezentacja na phpCE Polska 2017. Omawiam historię PHP oraz sposób, w jaki wykorzystujemy go dzisiaj. Pokazuję, w jaki sposób wybierać narzędzia i architekturę, aby nasze projekty żyły na produkcji długo i szczęśliwie.
Od codziennej higieny do strategicznej refaktoryzacjiMichał Bartyzel
• W jaki sposób już teraz możesz upiększyć swój kod?
• Jak refaktoryzować bez konieczności ukrywania tego w szacowaniach?
• Jak w ciągu 30 minut wyprostować najbardziej zagmatwany algorytm?
• W jaki sposób planować duże strategiczne refaktoryzacje?
• Jak w uporządkowany sposób przeprowadzać długotrwałe refaktoryzacje?
• Jak uniknąć niespójnej architektury w trakcie długotrwałej refaktoryzacji?
• Jak negocjować czas na refaktoryzację z Twoim managerem, PO czy klientem?
JDD 2016 - Wojciech Oczkowski - Testowanie Wydajnosci Za Pomoca Narzedzia JMHPROIDEA
W prezentacji pokażę jak wykorzystać narzędzie JMH do budowy microbenchmarków testujących wydajność zadanych kawałków kodu. Nabyte umiejętności pozwolą słuchaczom sprawdzić wydajność wybranych fragmentów kodu bez niebezpieczeństwa popełnienia, typowych dla tego typu testowania, błędów związanych z np. wygrzewaniem maszyny wirtualnej czy działalnością garbage collectora.
Techniki, czyli przekształcenia refaktoryzacyjne pomagają transformować fragmenty kodu z jednej postaci w inną. Jednak duże refaktoryzacje to przede wszystkim przedsięwzięcie organizacyjne. Co warto refaktoryzować? Jak zidentyfikować kluczowe problemy? Kiedy nie podejmować działań? Czy w ogóle warto? Jakie heurystyki i strategie wysokopoziomowe możesz wykorzystać? Odpowiedzi na te pytania poznasz podczas prelekcji Strategiczna refaktoryzacja.
GameDev od zaplecza
Nie samymi grami gamedev żyje. Z czasem, pojawiają się potrzeby dodania kolejnych klocków, wspólnych dla wszystkich gier, i nie koniecznie związanych z samym gameplayem. Zaczynamy przechodzić na ciemną stronę backendu tworząc serwisy rozszerzające naszą grę o, często niewidoczne dla graczy, ale istotne z punktu widzenia marketingu i analityki ficzery. Na przykładzie jednego z naszych serwisów pokażemy wam jakich technologii używamy w pracy, aby zapewnić stabilne działanie całej siatki ponad 200 mikroserwisów!
4Developers 2015: Przejrzysty i testowalny kod na Androidzie? Spróbujmy z Cle...PROIDEA
Michał Charmas
Language: Polish
Pisanie dobrego oprogramowania na platformę Android jest trudnym zadaniem.
Jednym z dużych problemów, zwłaszcza w przypadku sporych aplikacji, może być podział
logiki aplikacji tak, aby nasze Activity czy Fragmenty nie były nią przeładowane
oraz aplikacja była podatna na testowanie jednostkowe. Szukając pomysłu na
architekturę aplikacji, która będzie dobrze się skalowała wraz z rozwojem projektu,
natknąłem się na Clean Architecture zaproponowaną przez Boba C. Martina.
Podczas prezentacji zobaczymy czy i jak CA sprawdza się w przypadku
aplikacji mobilnych na Androida i na co pozwala jej zastosowanie. Oczywiście nie pominiemy
takich kluczowych kwestii jak pogodzenie tego wszystkiego z wszechobecną na Androidzie
asynchronicznością.
Wbrew powszechnym opiniom, nie tak prosto jest zrobić dobre Code Review. Robione w pośpiechu, tylko po to by je "odbębnić", często stwarza więcej szkody niż pożytku. Opowiem wam dlaczego code review jest ważne i jak wykorzystać ten proces aby upewnić się, że napisany kod jest najwyższej jakości. Będę nie tylko mówił o tym kto powinien robić code reviews, i dla kogo, jakie informacje są potrzebne do przeprowadzenia skutecznego code review, ale także jak zrobić dobre code review w najkrótszym możliwym czasie.
JDD2014: Strategiczna refaktoryzacja - Michał BartyzelPROIDEA
Techniki, czyli przekształcenia refaktoryzacyjne pomagają transformować fragmenty kodu z jednej postaci w inną. Jednak duże refaktoryzacje to przede wszystkim przedsięwzięcie organizacyjne. Co warto refaktoryzować? Jak zidentyfikować kluczowe problemy? Kiedy nie podejmować działań? Czy w ogóle warto? Jakie heurystyki i strategie wysokopoziomowe możesz wykorzystać? Odpowiedzi na te pytania poznasz podczas prelekcji Strategiczna refaktoryzacja.
Przez kilkanaście lat pracy zawodowej wielokrotnie padłem ofiarą mitów i przejściowych trendów przemysłu IT. Bałem się wysłać CV na widok ściany wymagań. Wprowadzałem Scruma "na siłę", przepisywałem systemy od zera, budowałem wymyślną architekturę. Umknęło mi wiele ważnych rzeczy, na które dziś pragnę zwrócić Waszą uwagę. Opowiem jak możecie ruszyć swoją karierę "z kopyta" poprzez skupienie się na 20% rzeczy, które dadzą 80% rezultatów. Pokażę, jakie praktyki realnie pozwoliły mi osiągać duże sukcesy u klientów z całego świata.
"Pitfalls of Object-Oriented Programming" [Polish] Prezentacja do wykładu przygotowanego na Koło Naukowe Twórców Gier "Polygon" na Politechnice Warszawskiej, a w drugiej wersji wygłoszonego także na AGH w Krakowie.
Opracowana na podstawie tekstu Fanatyzm obiektowy, przedstawia krytyczne podejście do projektowania i programowania obiektowego (m.in. pisania wrapperów na używane biblioteki, nadmiernej generalizacji, nadużywania dziedziczenia, enkapsulacji, wzorców projektowych) oraz jego negatywny wpływ na prostotę i czytelność kodu. Jako alternatywę prezentuje podejście DOD (Data-Oriented Design).
Published 2011-03-30
Zarządzanie złożonością - czyli jak budować, żeby nie żałować. Będzie to o strukturze aplikacji, narzędziach, metodologiach w zastosowaniu, czyli w sumie wszystkiego po trochu co trzeba wziąć pod uwagę rozpoczynając projekt.
Kamil Ruczyński - W jaki sposób ocenić czy test, który napisaliśmy dokładnie weryfikuje poprawność kodu? Można napisać test do testu i o tym w tej prezentacji, czyli o tak zwanych testach mutacyjnych.
W swojej prezentacji Wojtek Pilich pokaże z jakimi problemami mierzą się najczęściej początkujący programiści PHP, omówi to na przykładach realnego kodu. Pokaże też wskazówki jak unikać tych błędów i pisać czystszy, prostszy oraz bardziej optymalny kod w PHP.
Założenia, technologie, tips and tricks do codziennego zastosowania przy zabezpieczaniu aplikacji webowych od strony serwerowej. Analiza ruchu sieciowego w oparciu o narzędzia systemowe celem ułatwienia rozpoznania ewentualnych zagrożeń, monitorowanie usług.
Dlaczego ważne jest samodoskonalenie w zawodzie programisty? Czy dotyczy tylko początkujących? Prelekcja poruszy zarówno temat miękkiego wejścia w świat programowania PHP jak i koncentracji nad dalsza ścieżką w karierze.
The document discusses the SOLID principles of object-oriented design:
- The Single Responsibility Principle states that a class should have one single responsibility.
- The Open/Closed Principle states that software entities should be open for extension but closed for modification.
- The Liskov Substitution Principle states that objects should be replaceable with their subtypes without altering correctness.
- The Interface Segregation Principle states that many specific client interfaces are better than one general interface.
- The Dependency Inversion Principle states that high-level modules shouldn't depend on low-level modules but both should depend on abstractions.
2. O mnie
• Marek Keżel
• 7 lat doświadczenia w PHP (5.6, 7, 8, 9, 10, 11, 12 J)
• Programista w Innovation Software Sp. z o. o.
• Niezależny konsultant ds. oprogramowania w Specific Sp. z o. o.
• NDProdukcja – twórca wewnętrznego systemu ERP jednego z
największych producentów mebli tapicerowanych w Polsce
• Mąż i Tata
3. Agenda
•Czym jest refaktoryzacja
•Szybki przegląd technik refaktoryzacji
•Omówienie 8 wybranych technik
•Czemu nie zawsze będziesz refaktoryzował kod
•Pytania, sugestie, ewentualne wygwizdanie prelegenta
5. Czym jest refaktoryzacja ?
Refaktoryzacja to wymyślony proces przez rozpieszczonych
programistów, którzy myślą, że głupi ludzie zapłacą im ponownie za tą
samą pracę albo co gorsze za udawanie, że coś robią.
Janusz, dyrektor operacyjny, członek zarządu
6. Czym jest refaktoryzacja ?
The main purpose of refactoring is to fight technical debt. It transforms
a mess into clean code and simple design.
https://refactoring.guru/refactoring/what-is-refactoring
In computer programming and software design, code refactoring is the
process of restructuring existing computer code—changing the
factoring—without changing its external behavior. Refactoring is
intended to improve the design, structure, and/or implementation of
the software (its non-functional attributes), while preserving its
functionality.
https://en.wikipedia.org/wiki/Code_refactoring
7. Czym jest refaktoryzacja ?
Głównym celem przeprowadzania refaktoryzacji jest walka z długiem
technologicznym*, przeistoczenie brzydkiego kodu w czysty* ZROZUMIAŁY DLA
INNYCH.
*Dług technologiczny (Technical Debt) jest naszym mniej lub bardziej świadomym
działaniem, które ciągnie nasze oprogramowanie w dół. Ignorujemy dobre praktyki
w imię wyższych celów (tak nam się wydaje…) jak np. szybszy release przez co
pomijamy pisanie testów, nie kontrolujemy zależności, tworzymy niezrozumiałe
nazwy pól oraz metod. Czasami jesteśmy „dłużni” ponieważ robimy to
nieświadomie – nie mamy wiedzy jak coś zrobić lepiej. Czym się objawia dług?
Wydłużonym czasem wprowadzania zmian w kodzie, większą ilość błędów, coraz
większą ilością próśb o przeniesienie do innego projektu.
*Czysty kod (Clean Code) to taki który jest łatwy w utrzymaniu, zrozumiały dla
innych programistów (bez żadnej magii, dziwacznego nazewnictwa, rozdętych
metod oraz klas), bez zduplikowanego kodu, pozbawiony tzw. zapaszków (Code
Smells). Czysty kod czyta się jak dobrą książkę z uśmiechem a nie z przerażeniem w
stylu „co to $%^& jest !?”.
9. Kiedy wykonywać refaktoryzację ?
• Kiedy patrzymy na kod i czujemy, że skręca nas w środku na
sam widok – to jest idealny moment!
• Kiedy dodajemy nową funkcjonalność do naszego programu
(obie czynności traktujemy oddzielnie!)
• Kiedy naprawiamy jakiś problem
• Kiedy robimy codereview
• Kiedy robimy coś i mamy Déjà vu, że coś takiego już robiliśmy
10. Kiedy NIE wykonywać refaktoryzacji ?
• Kiedy nie rozumiemy kodu nad którym pracujemy
• Kiedy kod już działa produkcyjnie i nie ma z nim żadnych
problemów
• Kiedy projekt jest w stylu napisz i zapomnij
• Kiedy nie mamy pokrycia w testach tego co chcemy
zrefaktoryzować*
*dopiszemy te testy lub każdy z nas podejmie super ważną decyzje mając z
tyłu głowy złotą zasadę (przetestujemy na produkcji) J
11. Jak wykonać refaktoryzację ?
„Refaktoryzacja powinna być wykonana jako seria małych zmian które czynią
nasz kod lepszym, pozostawiając jednocześnie program w stanie gotowości”
• Jeżeli kod po wykonaniu refaktoryzacji dalej jest „brzydki” wracamy do
początku i robimy to jeszcze raz.
• Podczas refaktoryzacji nie powinny powstawać żadne nowe funkcjonalności
(proces refaktoryzacji powinien być oddzielny)
• Wszystkie istniejące testy muszą zostać poprawnie wykonane (czasami to
testy są winne niepowodzeń np. są zbyt nisko poziomowe, przez co musimy
dokonać refaktoryzacji samych testów)
https://refactoring.guru/refactoring/how-to
13. Kompozycja metod
• Extract Method
• Inline Method
• Extract Variable
• Inline Temp
• Replace Temp with Query
• Split Temporary Variable
• Remove Assignments to
Parameters
• Replace Method with Method
Object
• Substitute Algorithm
14. Przenoszenie funkcjonalności
• Move Method
• Move Field
• Extract Class
• Inline Class
• Hide Delegate
• Remove Middle Man
• Introduce Foreign Method
• Introduce Local Extension
15. Ogranizacja danych
• Change Value to Reference
• Change Reference to Value
• Duplicate Observed Data
• Self Encapsulate Field
• Replace Data Value with Object
• Replace Array with Object
• Change Unidirectional
Association to Bidirectional
• Change Bidirectional Association
to Unidirectional
• Encapsulate Field
• Encapsulate Collection
• Replace Magic Number with
Symbolic Constant
• Replace Type Code with Class
• Replace Type Code with
Subclasses
• Replace Type Code with
State/Strategy
• Replace Subclass with Fields
16. Upraszczanie wyrażeń regulanych
• Consolidate Conditional
Expression
• Consolidate Duplicate
Conditional Fragments
• Decompose Conditional
• Replace Conditional with
Polymorphism
• Remove Control Flag
• Replace Nested Conditional with
Guard Clauses
• Introduce Null Object
• Introduce Assertion
17. Upraszczanie wywołań metod / funkcji
• Add Parameter
• Remove Parameter
• Rename Method
• Separate Query from Modifier
• Parameterize Method
• Introduce Parameter Object
• Preserve Whole Object
• Remove Setting Method
• Replace Parameter with Explicit
Methods
• Replace Parameter with Method
Call
• Hide Method
• Replace Constructor with Factory
Method
• Replace Error Code with
Exception
• Replace Exception with Test
18. Upraszczanie abstrakcji
• Pull Up Field
• Pull Up Method
• Pull Up Constructor Body
• Push Down Field
• Push Down Method
• Extract Subclass
• Extract Superclass
• Extract Interface
• Collapse Hierarchy
• Form Template Method
• Replace Inheritance with
Delegation
• Replace Delegation with
Inheritance
20. UWAGA!
W celu uproszczenia a zarazem
zmieszczenia się w limicie
czasowym, nie wszystkie drobne
kroki refaktoryzacji zostaną
pokazane na slajdach.*
*Ale prowadzący o nich wspomni :)
22. Extract Method
Kiedy? Metoda ma za dużo odpowiedzialności (narusza SRP). Czujemy,
że coś nam nie pasuje.
Co zyskamy? Ograniczymy odpowiedzialność metody, zwiększymy
czytelność kodu.
Jak to zrobić? Tworzymy nową metodę (modyfikator dostępu?),
przenosimy fragment kodu do nowej metody, jeżeli kod korzysta ze
zmiennych zadeklarowanych wcześniej – przekazujemy je, w bazowej
metodzie odwołujemy się do nowo utworzonej, wykonujemy testy
Metoda odwrotna? Inline Method
23. Extract Method - przykład
class OptymalizerkaBoki
{
public function wyslijFormatkiNaOptymalizerke(array $formatki, int $optymalizerkaID): void
{
$formatkiWezglowia = [];
foreach ($formatki as $formatka) {
if ($formatka->czyWezglowie() === false) {
continue;
}
$formatkiWezglowia[] = $formatka;
}
$optymalizerkaWiadomosc = new OptymalizerkaWiadomosc();
$optymalizerkaWiadomosc->setFormatki($formatkiWezglowia);
$this->getBus($optymalizerkaID)->wyslij($optymalizerkaWiadomosc);
}
}
24. Extract Method - przykład
class OptymalizerkaBokiRefactoryzacja
{
public function wyslijFormatkiNaOptymalizerke(array $formatki, int $optymalizerkaID): void
{
$formatkiWezglowia = $this->wyfiltrujFormatkiWezglowia($formatki);
$optymalizerkaWiadomosc = new OptymalizerkaWiadomosc();
$optymalizerkaWiadomosc->setFormatki($formatkiWezglowia);
$this->getBus($optymalizerkaID)->wyslij($optymalizerkaWiadomosc);
}
private function wyfiltrujFormatkiWezglowia(array $formatki): array
{
$formatkiWezglowia = [];
foreach ($formatki as $formatka) {
if ($formatka->czyWezglowie() === false) {
continue;
}
$formatkiWezglowia[] = $formatka;
}
return $formatkiWezglowia;
}
}
26. Exctract Class
Kiedy? Klasa posiada wiele odpowiedzialności, robi za dużo, narusza zasadę
SRP (Single Responsibility Principle), jest mniej czytelna i trudna w analizie
Co zyskamy? Zbliżymy się albo osiągniemy zgodność z zasada SRP,
zwiększymy tolerancję na zmiany, poprawimy czytelność oraz zrozumienie
kodu
Jak to zrobić? Tworzymy nową klasę oraz tworzymy relację między klasami
(najlepiej jednokierunkową) przenosimy do niej docelową funkcjonalność
(korzystamy z technik Move Field i Move Method) uważamy na
modyfikatory dostępu (zaczynamy od prywatnych), wykonujemy testy
Wady? Zbyt często wykorzystywana, powoduje mnóstwo nowych klas często
małych i nie koniecznie z odpowiednimi odpowiedzialnościami
Metoda odwrotna? Inline Class
27. Extract Class - przykład
class SaturnService
{
public function __construct()
{
$this->client = new SoapClient(self::SATURN_API_WSDL, $this->options);
}
public function potwierdzZamowienieDoDostawcy(Zamowienie $zamowienie): void
{
// coś robimy z zamówieniem oraz pobieramy docID
$response = $this->potwierdzZamowienieWyslijRequest($saturnDocID);
//coś robimy z odpowiedzą dalsza cześc logiki
}
private function potwierdzZamowienieWyslijRequest(string $saturnDocID): array
{
$result = $this->client->ZdConfirm(['ZdConfirm' => ['DocID' => $saturnDocID]]);
// cos robimy z rezultatem
return ['stauts' => $result->status, 'confirmCode' => $result->confirmCode];
}
}
28. Extract Class - przykład
class SaturnApi implements SaturnApiInterface
{
public function __construct()
{
$this->soapClient = new SoapClient(self::SATURN_API_WSDL, $this->options);
}
public function potwierdzZamowienieWyslijRequest(string $saturnDocID): array
{
$result = $this->soapClient->ZdConfirm(['ZdConfirm' => ['DocID' => $saturnDocID]]);
// cos robimy z rezultatem
return ['stauts' => $result->status, 'confirmCode' => $result->confirmCode];
}
}
29. Extract Class - przykład
class SaturnService
{
public function __construct(SaturnApiInterface $api)
{
$this->apiClient = $api;
}
public function potwierdzZamowienieDoDostawcy(Zamowienie $zamowienie): void
{
// cos robimy z zamówieniem oraz pobieramy docID
$saturnDocID = '';
$response = $this->apiClient->potwierdzZamowienieWyslijRequest($saturnDocID);
//coś robimy z odpowiedzą dalsza cześc logiki
}
}
31. Replace Array With Object
Kiedy? Jak z danymi w tablicy musimy zrobić coś więcej niż tylko je
wyświetlić.
Co zyskamy? Ułatwimy pracę ze strukturą danych (dopilnujemy
właściwych danych we właściwych miejscach). Uzyskamy enkapsulację
– połączymy dane z funkcjonalnością – OOP.
Jak to zrobić? Tworzymy strukturę nowej klasy w oparciu o źródłową
tablicę, zmieniamy w kodzie każde użycie tablicy na nasz nowy obiekt
(jeżeli nie możemy, to musimy zaimplementować funkcjonalność tablicy
w naszej nowej klasie)
Wady? Obiekty są „wolniejsze” zajmują więcej pamięci*.
*https://stackoverflow.com/questions/3709578/using-arrays-vs-objects-for-storing-data
33. Replace Array With Object - przykład
class CentrumService
{
public function wyslijFormatkeDoCentrum(array $formatka): void
{
//czy struktura tablicy $formatka jest poprawna ?
$kubatura = $this->wyliczKubature($formatka);
$polePowierzchni = $this->wyliczPolePowierzchni($formatka);
...
}
public function wyliczKubature(array $formatki): float
public function wyliczPolePowierzchni(array $formatki): float
}
34. Replace Array With Object - przykład
class WyliczonaFormatka
{
private int $id;
private string $typ;
private string $nazwa;
…
public static function utworzZTablicy(array $formatka): self
{
//sprawdzenie poprawnosci otrzymanej tablicy
return new self($formatka['id'], $formatka['typ'], $formatka['nazwa']);
}
public function __construct(int $id, string $typ, string $nazwa)
public function getKubatura(): float
public function getPolePowierzchni(): float
}
35. Replace Array With Object - przykład
class CentrumService
{
public function wyslijFormatkeDoCentrum(WyliczonaFormatka
$wyliczonaFormatka): void
{
$kubatura = $wyliczonaFormatka->getKubatura();
$polePowierzchni = $wyliczonaFormatka->getPolePowierzchni();
...
}
}
37. Consolidate Duplicate Conditional Fragments
Kiedy? Posiadamy zduplikowany kod w różnych gałęziach warunkowych
Co zyskamy? Usuniemy zduplikowany kod J
Jak to zrobić? Przenosimy zduplikowany kod przed lub za (zależnie od
jego lokalizacji) instrukcje warunkowe
38. Consolidate Duplicate Conditional Fragments - przykład
public function actionCreate()
{
$zamowienie = new Zamowienie();
$zamowienie->load($this->request->post('zamowienie'));
if ($this->request->post('lozko')) {
$zamowienie->load($this->request->post('lozko'));
$zamowienie->save();
return $this->redirect(['index']);
} elseif ($this->request->post('szafka')) {
$zamowienie->load($this->request->post('szafka'));
$zamowienie->save();
return $this->redirect(['index']);
} else {
$zamowienie->save();
return $this->redirect(['index']);
}
}
39. Consolidate Duplicate Conditional Fragments - przykład
public function actionCreate()
{
$zamowienie = new Zamowienie();
$zamowienie->load($this->request->post('zamowienie'));
if ($this->request->post('lozko')) {
$zamowienie->load($this->request->post('lozko'));
} elseif ($this->request->post('szafka')) {
$zamowienie->load($this->request->post('szafka'));
}
$zamowienie->save();
return $this->redirect(['index']);
}
41. Replace Nested Conditional With Guard Clauses
Kiedy? Mamy mocno zagnieżdżone instrukcje warunkowe, które tworzą
kształt grotu strzały. Ciężko jest określić który warunek gdzie się kończy i
co robi
Co zyskamy? „Wyprostujemy” nasz kod, zlikwidujemy głębokie
zagnieżdżenia przez co zwiększymy czytelność kodu
Jak to zrobić? Wprowadzamy w każdej instrukcji warunkowej tzw.
Klauzule Ochronne (Guard Clauses), które automatycznie zwracają
jakąś wartość lub przerywają działanie programu wyjątkiem
42. Replace Nested Conditional With Guard Clauses - przykład
if ($zamowienie->czyZakonczone()) {
if ($zamowienie->getFirma()->nazwa === 'Januszex 2022 Sp. z. o.') {
$tranposrt = $this->spedytor->zarezerwujKubature($zamowienie->getKubatura());
$promocyjnaCena = $this->cennik->standardowaCena() * 5;
$faktura = $this->rozliczenia->wygenerujFakture($zamowienie);
$this->printer->drukuj($faktura);
} else {
$cena = $this->cennik->standardowaCena();
$this->mailer->wyslijZamowienie($zamowienie, $cena);
}
return $this->redirect(['index']);
} else {
throw new Exception('Tylko zakończone zamówienia.');
}
43. Replace Nested Conditional With Guard Clauses - przykład
if ($zamowienie->czyZakonczone() === false) {
throw new Exception('Tylko zakończone zamówienia.');
}
if ($zamowienie->getFirma()->nazwa === 'Januszex 2022 sp. z. o.') {
$tranposrt = $this->spedytor->zarezerwujKubature($zamowienie->getKubatura());
$promocyjnaCena = $this->cennik->standardowaCena() * 5;
$faktura = $this->rozliczenia->wygenerujFakture($zamowienie);
$this->printer->drukuj($faktura);
return $this->redirect(['index']);
}
$cena = $this->cennik->standardowaCena();
$this->mailer->wyslijZamowienie($zamowienie, $cena);
return $this->redirect(['index']);
45. Introduce Parameter Object
Kiedy? Mamy powiązane ze sobą parametry metody, które na dodatek
pojawiają się w różnych metodach. Uwaga!
Co zyskamy? Pozbywamy się zduplikowanego kodu który jest związany
z logiką parametrów, zmniejszamy liczbę parametrów przekazywanych
do metody, zwiększamy czytelność kodu
Jak to zrobić? Tworzymy klasę, która będzie reprezentować nasze
parametry, metody które używały naszych parametrów zmieniamy tak
aby przyjmowały zamiast nich obiekt typu klasy którą stworzyliśmy,
zmieniamy odwołania do parametrów wewnątrz metod na pola,
metody z nowego obiektu
Wady? Technika ta czasami prowadzi do tworzenia klas pozbawionych
funkcjonalności – pojemników na same dane. Co jest nie zgodne z
zasadami OOP.
46. Introduce Parameter Object - przykład
class PracownikUrlop
{
public function getIloscDniPracujacych(
DateTime $poczatek,
DateTime $koniec): int
{
$iloscDniPracujacych = 0;
if ($poczatek > $koniec) {
throw new Exception('Błędny zakres dat.');
}
$period = new DatePeriod($poczatek,
new DateInterval('P1D'),
$koniec);
foreach ($period as $date) {
if ($date->format('N') < 6) {
$iloscDniPracujacych++;
}
}
}
return $iloscDniPracujacych;
}
public function getUrlop(DateTime $poczatek,
DateTime $koniec): array
{
if ($poczatek > $koniec) {
throw new Exception('Błędny zakres dat.');
}
...
}
}
47. Introduce Parameter Object - przykład
class ZakresDat
{
public function __construct(DateTime
$poczatek, DateTime $koniec)
{
if ($poczatek > $koniec) {
throw new Exception('Błędny zakres dat.');
}
}
public function getPoczatek(): DateTime
public function getKoniec(): DateTime
public function getPeriod(): DatePeriod
{
return new DatePeriod($this->poczatek,
new DateInterval('P1D'),
$this->koniec);
}
}
class PracownikUrlop
{
public function getIloscDniPracujacych(
ZakresDat $zakresDat): int
{
$iloscDniPracujacych = 0;
foreach ($zakresDat>getPeriod() as $date) {
if ($date->format('N') < 6) {
$iloscDniPracujacych++;
}
}
return $iloscDniPracujacych;
}
public function getUrlop(ZakresDat $zakresDat): array
{
...
}
}
49. Replace Error Code with Exception
Kiedy? Chcemy zwrócić jakąś wartość do kodu klienckiego oraz w przypadku
błędu zakomunikować to razem z kodem błędu, lecz nie wiemy do końca jak
to zrobić i sięgamy do sposobów z proceduralnego podejścia tylko, że
zapominamy, że obracamy się w obiektowym świecie, poza tym np. nasza
metoda zwraca więcej niż jeden typ.
Co zyskamy? Uciekniemy od proceduralnego paradygmatu i wrócimy w
ramiona OOP, uściślimy zwracany typ danych z metody, wyjątki oprócz kodów
błędów mogę przechowywać dodatkowe informacje np. opis błędu
Jak to zrobić? Zmieniamy wszystkie sprawdzanie zwracanych kodów błędów
na bloki try-catch, wewnątrz metody rzucamy wyjątki zamiast zwracania
kodów błędów
Wady? Używanie wyjątków do przekazywania komunikatów powoduje wystp
wielu bloków try-catch. Pamiętajmy, że wyjątki służą do komunikowania o
błędach!
50. Uwaga!
Technika to operuje na zwracanym
kodzie błędu – l. całkowita. W
przykładzie posłużę się zamiast tego
tablicą – niestety dość często
stosowanym rozwiązaniem w PHP
51. Replace Error Code* with Exception - przykład
public function wyliczCene(ZamowieniePozycja $pozycja): array
{
if ($pozycja->getFirma()->nazwa === 'Januszex 2022 sp. z o. o.') {
return [
'status' => 'error',
'msg' => 'Tej firmy nie obsługujemy!'
];
}
if ($pozycja->czyLozko() === false) {
return [
'status' => 'error',
'msg' => 'Wyliczamy cenę tylko dla łóżek'
];
}
return [
'status' => 'success',
'cena_netto' => $this->bardzoZaawansowanaLogika($pozycja),
];
}
52. Replace Error Code* with Exception - przykład
$cenaNetto = $cennik->wyliczCeneNetto($pozycja);
if ($cenaNetto['status'] === 'error') {
//tutaj obsługujemy błąd
}
$pozycjaFaktury->cenaNetto = $cenaNetto['cena_netto'];
53. Replace Error Code* with Exception - przykład
class Cennik
{
public function wyliczCeneNetto(ZamowieniePozycja $pozycja): float
{
if ($pozycja->getFirma()->naz === 'Januszex 2022 sp. z o. o.') {
throw new TejFirmyNieObslugujemyException(
'Tej firmy nie obslugujemy!'
);
}
if ($pozycja->czyLozko() === false) {
throw new BlednyTypPozycjiException(
'Wyliczamy cenę tylko dla łóżek'
);
}
return $this->bardzoZaawansowanaLogika($pozycja);
}
}
56. Extract Subclass
Kiedy? Nasza klasa posiada pola oraz metody używane tylko w jednym
określonym przypadku. Mimo że ten konkretny przypadek wygląda na
odrębny to jest powiązany w jakiś sposób z ogólnym kontekstem przez
co nie może zostać wyodrębniony do w pełni niezależnej klasy.
Co zyskamy? Konkretyzację przypadków z wyodrębnioną logiką
powiązaną właśnie z tym przypadkiem, będziemy mogli łatwo tworzyć
nowe przypadki jako podklasy
Jak to zrobić? Zmieniamy
Wady? Ta technika jest niemożliwa lub trudna w implementacji w
przypadku bardzo rozbudowanych hierarchii klas.
57. Extract Subclass - przykład
class Akord
{
private $tkaninaID;
private $ramaLozkaID;
private $czyOtwieranaPufa;
public function wyliczCzas(): int
{
$this->przypiszParametryDoWzorow();
$this->wylicz();
$this->optymalizujCzas();
return $this->wyliczonyCzas;
}
private function przypiszParametryDoWzorow(): void
{
//logika przypisywania
if ($this->pozycja->czyLozko()) {
$this->przypiszParametryLozkaDoWzorow();
}
}
private function optymalizujCzas(): void
}
58. Extract Subclass - przykład
class Akord
{
protected int $tkaninaID;
public function wyliczCzas(): int
{
$this->przypiszParametryDoWzorow();
$this->wylicz();
$this->optymalizujCzas();
return $this->wyliczonyCzas;
}
protected function przypiszParametryDoWzorow(): void
{
//logika przypisywania
}
private function optymalizujCzas(): void
}
class AkordLozko extends Akord
{
private int $ramaLozkaID;
private bool $czyOtwieranaPufa;
protected function przypiszParametryDoWzorow(): void
{
parent::przypiszParametryDoWzorow();
//specjalna logika oparta o typ pozycji = łózko
}
}
60. Czemu nie zawsze będziesz refaktoryzował kod ?
Ponieważ:
• Nie będziesz miał na to czasu – szybki realease, szybka poprawka
błędu itd.
• Nie będziesz potrafił tego zrobić - mam nadzieje, że ta prezentacja
trochę Ci pomoże
• Nikt nie będzie chciał Ci za to zapłacić – a wiadomo za friko to można
pisać ToDo listy ucząc się nowego frameworka w JS’ach
• Nie będziesz umiał uargumentować zasadności refaktoryzacji ze
strony biznesowej dla przełożonego, zleceniodawcy - postaram się coś
podpowiedzieć
• Nie zrobisz tego, bo nie! - podejmiesz świadomą decyzję z którą
będziesz musiał żyć :)
61. Jak przekonać biznes do refaktoryzacji
• Zrozumieć płaszczyznę, po której porusza się biznes – pieniądze!
• Jeżeli Twoja praca nie przyniesie pieniędzy (zysku) to po co szef / inwestor ma za
to płacić ?
• Pamiętaj, że Twój czas to ich pieniądze !
• Przekonaj ludzi od biznesu, że refaktoryzacja jest inwestycją pełną zysków, tylko,
że w dłuższym terminie.
• Termin ten to nic innego jak przyszłe wdrożenia nowych funkcjonalności lub
utrzymanie istniejącego kodu.
• Owszem na początku ”trzymanie się zasad” wydłuża czas wytwarzania
oprogramowania przez co więcej kosztuje, ale w późniejszym czasie te wartości
się odwracają
• Uwaga! Jeżeli produkt nad którym pracujesz nie ma w planach być rozwijany,
utrzymywany albo jest MVP (minimum viable product) – odpuść refaktoryzację,
oni mają racje, że nie chcą za to zapłacić J