{"id":21644,"date":"2023-05-22T05:00:00","date_gmt":"2023-05-22T03:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=21644"},"modified":"2024-07-22T14:58:53","modified_gmt":"2024-07-22T12:58:53","slug":"rozwoj-oprogramowania-refaktoryzacja","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/rozwoj-oprogramowania-refaktoryzacja\/","title":{"rendered":"Rozw\u00f3j oprogramowania \u2013 refaktoryzacja"},"content":{"rendered":"\n<p>Poj\u0119cie refaktoryzacji mo\u017ce by\u0107 interpretowane dwojako. Z jednej strony mo\u017ce by\u0107 rozumiane jako czynno\u015b\u0107 \u00ad\u2013 czasownik. Wtedy przez refaktoryzacj\u0119 rozumiemy ulepszenie kodu, kt\u00f3ry ju\u017c powsta\u0142, pami\u0119taj\u0105c, \u017ce nie zmieniamy dzia\u0142ania kodu, kt\u00f3ry ju\u017c zosta\u0142 napisany. Innymi s\u0142owy, nie powinni\u015bmy by\u0107 zaskoczeni, \u017ce funkcjonalno\u015b\u0107 kodu nie uleg\u0142a zmianie, poniewa\u017c nie dodajemy nowych mechanizm\u00f3w. Poj\u0119cie refaktoryzacji mo\u017ce by\u0107 tak\u017ce rzeczownikiem, oznaczaj\u0105cym zmian\u0119, kt\u00f3rej dokonujemy.<\/p>\n\n\n\n<p>Zanim podejmiemy si\u0119 refaktoryzacji, powinni\u015bmy rozwa\u017cy\u0107 kilka krok\u00f3w. Bardzo cz\u0119sto przez refaktoryzacj\u0119 rozumiany jest skrajny przypadek \u2013 siadamy, przepisujemy p\u00f3\u0142 systemu, modu\u0142 lub by\u0107 mo\u017ce n modu\u0142\u00f3w. <strong>Z czasem zauwa\u017cono, \u017ce znacznie lepsz\u0105, bezpieczniejsz\u0105, poprawn\u0105 opcj\u0105 jest zupe\u0142nie inne podej\u015bcie, czyli przeprowadzanie wielu bardzo ma\u0142ych zmian najcz\u0119\u015bciej w wi\u0119kszej ilo\u015bci.<\/strong><\/p>\n\n\n\n<p>Zmiana nazwy zmiennej, nazwy metody s\u0105 to podstawy, kt\u00f3re ka\u017cdy wielokrotnie realizowa\u0142, jednak te kroki r\u00f3wnie\u017c s\u0105 uznawane za refaktoryzacj\u0119. Lepiej wprowadzi\u0107 n ma\u0142ych, bezpiecznych zmian ni\u017c rozgrzeba\u0107 po\u0142ow\u0119 systemu, co mo\u017ce doprowadzi\u0107 do jego zatrzymania. Nale\u017cy podejmowa\u0107 kroki technik\u0105 asekuracyjn\u0105. Trzymaj\u0105c si\u0119 tej zasady, poprawia si\u0119 nam nawet estymacja czasu. Ryzyko niepotrzebnego spalenia du\u017cej ilo\u015bci czasu b\u0119dzie mniejsze.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Refaktoryzacja \u2013 kiedy jest potrzebna?<\/strong><\/h2>\n\n\n\n<p>Niejednokrotnie trudno jest odpowiedzie\u0107 sobie na pytanie, kiedy powinni\u015bmy zacz\u0105\u0107 co\u015b poprawia\u0107. Ka\u017cdy z nas musi nauczy\u0107 si\u0119, kiedy i jak podejmowa\u0107 si\u0119 refaktoryzacji. Problemem jest tutaj to, \u017ce nie da si\u0119 tego wyja\u015bni\u0107 w ksi\u0105\u017ckowy, zero-jedynkowy spos\u00f3b. Jest to co\u015b, co poznajemy z czasem, ucz\u0105c si\u0119 szacowa\u0107 korzy\u015bci i straty. Inaczej m\u00f3wi\u0105c, <strong>ka\u017cda zmiana na poziomie kodu, wprowadzenie wzorca projektowego, dodatkowej abstrakcji, zmiana API ma swoje konsekwencje, kt\u00f3re zmusz\u0105 nas do wprowadzenia zmian na poziomie kodu<\/strong>, np. zmiany kompatybilno\u015bci.<\/p>\n\n\n\n<p>Z drugiej strony, z ka\u017cd\u0105 zmian\u0105 mo\u017cemy co\u015b zyska\u0107. By\u0107 mo\u017ce wi\u0119ksz\u0105 elastyczno\u015b\u0107, wi\u0119ksz\u0105 \u0142atwo\u015b\u0107 wymiany implementacji, wi\u0119ksz\u0105 generyczno\u015b\u0107, kt\u00f3ra pozwoli nam w przysz\u0142o\u015bci \u0142atwiej wprowadzi\u0107 now\u0105 funkcjonalno\u015b\u0107. Dobrym przyk\u0142adem mo\u017ce by\u0107 zamiana instrukcji warunkowych na enumy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Przyk\u0142ad<\/strong><\/h3>\n\n\n\n<p>Przeanalizujmy przyk\u0142ad, w kt\u00f3rym mamy do obs\u0142ugi nowe API. W ramach przyk\u0142adu API ma dost\u0119pne tylko metody typu CRUD, kt\u00f3re przyjmuj\u0105 odpowiedni obiekt implementuj\u0105cy InformationType w zale\u017cno\u015bci od rodzaju operacji. Za\u0142\u00f3\u017cmy, \u017ce w tym momencie jeste\u015bmy na etapie implementacji uzupe\u0142niania danych do metod API. Najprostszym rozwi\u0105zaniem by\u0142oby obs\u0142u\u017cenie go za pomoc\u0105 if\u00f3w\/switch\u00f3w.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/1-1.png\"><img decoding=\"async\" width=\"485\" height=\"559\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/1-1.png\" alt=\"przyk\u0142ad refaktoryzacji\" class=\"wp-image-21645\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/1-1.png 485w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/1-1-260x300.png 260w\" sizes=\"(max-width: 485px) 100vw, 485px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Nie s\u0105 to jednak zbyt dobre rozwi\u0105zania. Dodajemy nowy kod oparty na instrukcjach warunkowych \u2013ifach, switach, co nie jest najlepszym i czytelnym podej\u015bciem, poniewa\u017c taki kod prawdopodobnie b\u0119dzie si\u0119 rozrasta\u0142 w przysz\u0142o\u015bci. Osoba pisz\u0105ca kod b\u0119dzie dodawa\u0107 kolejne instrukcje warunkowe, co pogorszy jako\u015b\u0107, czytelno\u015b\u0107 i skomplikowanie logiki, jak i test\u00f3w. Innym mo\u017cliwym rozwi\u0105zaniem mo\u017ce by\u0107 zastosowanie np. wzorca Chain of Responsibility.<\/p>\n\n\n\n<p>Cz\u0119sto zdarza si\u0119, \u017ce firma wystawiaj\u0105ca API wprowadza nowe wersje, modyfikuj\u0105c przy tym m.in. wej\u015bciowe struktury danych. <strong>Powy\u017cszy kod da si\u0119 zast\u0105pi\u0107 przy pomocy enuma, nie u\u017cywaj\u0105c instrukcji warunkowych.<\/strong> W przysz\u0142o\u015bci pozwoli na \u0142atwiejsze ponowne wykorzystanie zaimplementowanego mechanizmu lub rozszerzenie go na nowe wersje, funkcjonalno\u015bci danego API.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/2-1.png\"><img decoding=\"async\" width=\"601\" height=\"659\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/2-1.png\" alt=\"Zast\u0105pienie kodu za pomoc\u0105 enuma\" class=\"wp-image-21648\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/2-1.png 601w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/2-1-274x300.png 274w\" sizes=\"(max-width: 601px) 100vw, 601px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Ca\u0142e wywo\u0142anie b\u0119dzie wygl\u0105da\u0107 nast\u0119puj\u0105co:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/3-1.png\"><img decoding=\"async\" width=\"579\" height=\"127\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/3-1.png\" alt=\"Gotowy kod\" class=\"wp-image-21650\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/3-1.png 579w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/3-1-300x66.png 300w\" sizes=\"(max-width: 579px) 100vw, 579px\" \/><\/a><\/figure><\/div>\n\n\n\n<p><a href=\"https:\/\/github.com\/ArticleAboutRefactoring\/ConvertingIfologyToEnum\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Ca\u0142y kod mo\u017cna znale\u017a\u0107 tutaj<\/a>. W tym miejscu warto zatrzyma\u0107 si\u0119 na chwil\u0119 i zastanowi\u0107, czy oczekiwany rezultat z zastosowania enuma nie jest tak naprawd\u0119 odpowiedz\u0105, dlaczego decydujemy si\u0119 po\u015bwi\u0119ci\u0107 czas na refaktoryzacj\u0119. Dlaczego to robimy? Odpowied\u017a jest prosta \u2013 tak, to w\u0142a\u015bnie g\u0142\u00f3wny cel refaktoringu.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Refaktoryzacja \u2013 wa\u017cne kwestie<\/strong><\/h2>\n\n\n\n<p>Zastanawiaj\u0105c si\u0119 dalej nad refaktoringiem, zapewne pojawi\u0105 si\u0119 kolejne w\u0105tpliwo\u015bci:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Kiedy dokonujemy refaktoryzacji?<\/li><li>Czy zatrzymujemy si\u0119, chc\u0105c dokona\u0107 refaktoryzacji i przez d\u0142ugie dni\/tygodnie nie robimy nic nowego, aby m\u00f3c wykona\u0107 refaktoryzacj\u0119? Czy mo\u017ce jednak jest to co\u015b, co powinni\u015bmy wykonywa\u0107 na bie\u017c\u0105co?<\/li><li>Kto powinien robi\u0107 refaktoryzacj\u0119? Wyznaczone osoby, czy mo\u017ce wszyscy?<\/li><li>Czy jest \u201clepszy\u201d moment, aby refaktoryzowa\u0107?<\/li><li>Czy wzorce projektowe to wszystko, czego potrzebujemy do refaktoryzacji?<\/li><\/ul>\n\n\n\n<p>Odpowiedzi na te pytania mog\u0105 nie by\u0107 zawsze jasne, jednak w dzisiejszych czasach si\u0119 ustabilizowa\u0142y. W wi\u0119kszo\u015bci przypadk\u00f3w jako dobr\u0105 praktyk\u0119 refaktoryzacji, powinni\u015bmy j\u0105 przeprowadza\u0107 w spos\u00f3b ci\u0105g\u0142y. Powinien j\u0105 robi\u0107 ka\u017cdy w zespole, ka\u017cdego dnia.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Kiedy jest najlepszy czas na refaktoryzacj\u0119?<\/strong><\/h2>\n\n\n\n<p><strong>Gdy planujemy doda\u0107 do naszego kodu now\u0105 funkcj\u0119<\/strong><\/p>\n\n\n\n<p>Mo\u017cemy wtedy zastanowi\u0107 si\u0119, czy nie da\u0142oby si\u0119 go wprowadzi\u0107 \u0142atwiej\/szybciej, gdyby najpierw wprowadzi\u0107 poprawki w kodzie. Lepszy kod pozwoli\u0142by napisa\u0107 \u201c\u0142atwe\u201d testy. Takie podej\u015bcie proponuj\u0105 mi\u0119dzy innymi Martin Fowler i Kent Beck w jednej ze swoich ksi\u0105\u017cek.<\/p>\n\n\n\n<p><strong>Po zako\u0144czeniu implementacji danej funkcji<\/strong><\/p>\n\n\n\n<p>Ten moment wydaje si\u0119 by\u0107 zupe\u0142nie naturalny i prawdopodobnie jest to podej\u015bcie najcz\u0119\u015bciej stosowane przez osoby implementuj\u0105ce dane rozwi\u0105zanie. Jest on integralnym krokiem TDD. Mo\u017cemy si\u0119 wtedy na chwil\u0119 zatrzyma\u0107 i poprawi\u0107 napisany przed chwil\u0105 kod. Mamy wtedy gotow\u0105 i przetestowan\u0105 logik\u0119 nowej funkcjonalno\u015bci. Nieraz mo\u017cemy zauwa\u017cy\u0107, \u017ce cz\u0119\u015b\u0107 mogliby\u015bmy zrobi\u0107 lepiej\/ciekawiej pod k\u0105tem przysz\u0142ego utrzymania.<\/p>\n\n\n\n<p><strong>Gdy poznajemy nowy kod<\/strong><\/p>\n\n\n\n<p>Z czasem nawet utar\u0142y si\u0119 s\u0142owa, \u017ce osoby tworz\u0105ce oprogramowanie cz\u0119\u015bciej czytaj\u0105 kod ni\u017c go tworz\u0105 lub \u2013 dok\u0142adniej m\u00f3wi\u0105c \u2013 rozwijaj\u0105. Brak zrozumienia i utrzymania istniej\u0105cego kodu jest recept\u0105 na katastrof\u0119!<\/p>\n\n\n\n<p><strong>Gdy ca\u0142y zesp\u00f3\u0142 prowadzi refaktoring przez kilka dni, a nawet d\u0142u\u017cej<\/strong><\/p>\n\n\n\n<p>Taki moment powinien by\u0107 jednak wyj\u0105tkiem od regu\u0142y. Mo\u017ce si\u0119 zdarzy\u0107 np. gdy planujemy migracj\u0119 pomi\u0119dzy narz\u0119dziami. Kolokwialnie m\u00f3wi\u0105c, o kod powinni\u015bmy dba\u0107 tak, jak dbamy o porz\u0105dek w swoich domach, gdzie wynosimy \u015bmieci, sprz\u0105tamy co 2-3 dni.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dodatkowe wskaz\u00f3wki<\/strong><\/h2>\n\n\n\n<p>Codzienne podnoszenie jako\u015bci, podejmowanie pewnych krok\u00f3w prze\u0142o\u017cy si\u0119 na to, \u017ce dodawanie nowych funkcjonalno\u015bci b\u0119dzie du\u017co szybsze, \u0142atwiejsze, sprawniejsze, co ostatecznie wp\u0142ynie na jako\u015b\u0107 kodu. Tutaj widzimy, \u017ce trudno m\u00f3wi\u0107 o refaktoryzacji, maj\u0105c du\u017ce sprz\u0119\u017cenie i nisk\u0105 sp\u00f3jno\u015b\u0107, czyli z\u0142y podzia\u0142 odpowiedzialno\u015bci.<\/p>\n\n\n\n<p>Id\u0105c dalej, mo\u017cemy powiedzie\u0107, \u017ce ju\u017c na tym poziomie mog\u0105 by\u0107 naruszone niekt\u00f3re z podstawowych dobrych praktyk pisania kodu \u2013 zasady SOLID<a href=\"#_edn1\" id=\"_ednref1\" rel=\"nofollow\" >[i]<\/a>, KISS<a href=\"#_edn2\" id=\"_ednref2\" rel=\"nofollow\" >[ii]<\/a>czy TDA<a href=\"#_edn3\" id=\"_ednref3\" rel=\"nofollow\" >[iii]<\/a>. Bez odpowiedniego podzia\u0142u odpowiedzialno\u015bci nie mamy czystego kodu, czyli ju\u017c na tym poziomie ci\u0119\u017cko m\u00f3wi\u0107 o refaktoryzacji.<\/p>\n\n\n\n<p>Dodatkowo, je\u015bli kod nie jest czysty, to zwykle nie mamy do niego test\u00f3w b\u0119d\u0105cych naszym zapleczem bezpiecze\u0144stwa. <strong>Tak naprawd\u0119 nie da si\u0119 pomin\u0105\u0107 \u017cadnego z tych trzech element\u00f3w \u2013<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong>czystego kodu,<\/strong><\/li><li><strong>refaktoryzacji,<\/strong><\/li><li><strong>testowania.<\/strong><\/li><\/ul>\n\n\n\n<p>Nale\u017cy wykonywa\u0107 wszystko razem inaczej szybko mo\u017cna si\u0119 zniech\u0119ci\u0107, bo kt\u00f3ry\u015b z element\u00f3w mo\u017ce by\u0107 trudny do poprawnego zaimplementowania.<\/p>\n\n\n\n<p>Najwa\u017cniejsze jest to, aby osoba pracuj\u0105ca z kodem to wszystko wywa\u017cy\u0142a, poniewa\u017c czasami warto\u015b\u0107 korzy\u015bci b\u0119dzie niewielka, nawet niezauwa\u017calna. M\u00f3wi\u0105c inaczej, po co robi\u0107 bardziej generyczny kod teraz, skoro by\u0107 mo\u017ce w przysz\u0142o\u015bci nikt nie b\u0119dzie go potrzebowa\u0142. Nale\u017cy uwa\u017ca\u0107, aby nie popa\u015b\u0107 w pu\u0142apk\u0119 robienia zbyt elastycznego rozwi\u0105zania. Nale\u017cy robi\u0107 rzeczy iteracyjnie, gdy\u017c cz\u0119sto warto poczeka\u0107, ze zmianami, a\u017c pewne rzeczy stan\u0105 si\u0119 jasne. Dok\u0142adniej m\u00f3wi nam o tym zasada YAGNI<a href=\"#_edn4\" id=\"_ednref4\" rel=\"nofollow\" >[iv]<\/a>.<\/p>\n\n\n\n<p>Nale\u017cy jednak pami\u0119ta\u0107, \u017ce wprowadzaj\u0105c refaktoryzacj\u0119, nie wprowadzamy nowych funkcjonalno\u015bci, co od razu stawia zasad\u0119, \u017ce refactoring musi by\u0107 bezpieczny. Refaktoryzacja w oderwaniu od test\u00f3w, czystego kodu, dobrej architektury i wielu innych czynnik\u00f3w b\u0119dzie mia\u0142a bardzo ma\u0142y sens. Recept\u0105 na niez\u0142amanie wspomnianej przed chwil\u0105 zasady jest istnienie dobrych test\u00f3w. <strong>W przeciwnym wypadku refaktoryzacja mo\u017ce sta\u0107 si\u0119 bardzo trudna i niebezpieczna.<\/strong> Mo\u017ce si\u0119 te\u017c okaza\u0107, \u017ce b\u0119dzie mia\u0142a ona niewielki sens oraz b\u0119dzie du\u017co bardziej kosztowna ni\u017c gdyby\u015bmy si\u0119 jej nie podj\u0119li.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Syndromy Code Smells<\/strong><\/h2>\n\n\n\n<p>Wiemy ju\u017c, przynajmniej w teorii, jak i kiedy wykonywa\u0107 refaktoryzacj\u0119, ale z drugiej strony mamy syndromy, na kt\u00f3re musimy by\u0107 wyczuleni. Potocznie zwane <strong>code smell<\/strong>, kt\u00f3re powinny by\u0107 ostrze\u017ceniem, \u017ce co\u015b jest nie tak. Wiele z nich jest zupe\u0142nie naturalnych, stosowanych na co dzie\u0144, np. z\u0142e nazewnictwo, prze\u0142adowanie odpowiedzialno\u015bci.<\/p>\n\n\n\n<p>Zapami\u0119tanie wszystkich code smells mo\u017ce by\u0107 problematyczne. Znacz\u0105co lepiej jest najpierw si\u0119 z nimi zapozna\u0107, a gdy pojawi si\u0119 problem odszuka\u0107 dany code smell i sprawdzi\u0107, jak najlepiej sobie z nim poradzi\u0107. Wi\u0119cej szczeg\u00f3\u0142\u00f3w mo\u017cna przeczyta\u0107 na stronie <a href=\"https:\/\/sourcemaking.com\/refactoring\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >sourcemaking<\/a>. Pisa\u0142 o tym nawet autor wymienionych artyku\u0142\u00f3w i ksi\u0105\u017cki.<\/p>\n\n\n\n<p>Wymienienie i opisanie wszystkich code smells to temat na osobny artyku\u0142. Dla dok\u0142adnego zapoznania si\u0119 z poni\u017cszymi polecam artyku\u0142 <a href=\"https:\/\/sourcemaking.com\/refactoring\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >o technikach refaktoringu i bad code smells.<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Zestaw najcz\u0119stszych code smells\/przyczyn niskiej jako\u015bci kodu<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Brak trzymania si\u0119 zasad SOLID, KISS \u2013 przesada z abstrakcjami, YAGNI, DRY<a id=\"_ednref1\" href=\"#_edn1\" class=\"ek-link\" rel=\"nofollow\" >[v]<\/a>, TDA itp.<\/li><li>Obsesja na punkcie typ\u00f3w prymitywnych, co powoduje, \u017ce kod jest mniej obiektowy. Mo\u017ce przypomina\u0107 podej\u015bcie proceduralne co cz\u0119sto przek\u0142ada si\u0119 na ifowanie, switchowanie zamiast polimorfizmu. Przyk\u0142ad, jak tego unika\u0107 by\u0142 om\u00f3wiony wcze\u015bniej, np. <a aria-label=\" (opens in a new tab)\" href=\"https:\/\/github.com\/ArticleAboutRefactoring\/ConvertingIfologyToEnum\/blob\/main\/src\/main\/java\/pl\/training\/movies\/afterrefactor\/MovieType.java\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >MovieType<\/a>.<\/li><li>Z\u0142e zaprojektowanie systemu na poziomie obiekt\u00f3w. Zbyt d\u0142uga lista argument\u00f3w. Maksymalna rekomendowana ilo\u015b\u0107 to 3.<\/li><li>Mo\u017ce si\u0119 zdarzy\u0107, \u017ce mamy duplikacj\u0119 kodu w r\u00f3\u017cnych cz\u0119\u015bciach kodu, czyli mamy r\u00f3\u017cne klasy, r\u00f3\u017cne kontrakty, ale powt\u00f3rzon\u0105 logik\u0119 w metodach klas.<\/li><li>Nieodpowiednia segregacja odpowiedzialno\u015bci. Wprowadzenie jednej funkcji powoduje zmiany w wielu miejscach, klasach, typach.<\/li><li>Brak dobrych test\u00f3w, brak pokrycia kodu testami.<\/li><li>Brak wstrzykiwania zale\u017cno\u015bci.<\/li><li>Nadu\u017cywanie programowania imperatywnego, a dok\u0142adniej prze\u0142adowanie ifami, switachami.<\/li><li>Instancyjne pola tymczasowe zamiast zmiennych lokalnych w metodach.<\/li><li>Du\u017ce sprz\u0119\u017cenie i niska sp\u00f3jno\u015b\u0107:<ul><li>Sprz\u0119\u017cenie \u2013 inaczej m\u00f3wi\u0105c si\u0142a z jak\u0105 wsp\u00f3\u0142pracuj\u0105 elementy. Nie wa\u017cne czy to metoda, komponent czy mo\u017ce mikroserwis. Im wi\u0119ksze sprz\u0119\u017cenie, powi\u0105zanie tym wi\u0119ksze k\u0142opoty patrz\u0105c pod k\u0105tem refaktoryzacji, zmian, utrzymania, testowania. Nale\u017cy d\u0105\u017cy\u0107 do jak najmniejszego sprz\u0119\u017cenia.<\/li><li>Sp\u00f3jno\u015b\u0107 \u2013 kohezja, czyli d\u0105\u017cymy do tego, aby komponent, serwis skupia\u0142 si\u0119 na jednej dobrze zdefiniowanej rzeczy. Im wi\u0119ksza sp\u00f3jno\u015b\u0107 tym lepiej.<\/li><\/ul><\/li><li>B\u0142\u0119dy pope\u0142niane na poziomie analizy, projektowania oraz implementacji.<\/li><li>Nieodpowiednie zarz\u0105dzanie zasobami \u2013 presja czasu, zbyt ma\u0142o ludzi w zespole, z\u0142a estymacja.<\/li><li>Z\u0142o\u017cono\u015b\u0107 problem\u00f3w \u2013 dodawanie nowych funkcjonalno\u015bci, ka\u017cdy rozw\u00f3j bez refaktoringu b\u0119dzie wprowadza\u0107 chaos.<\/li><li>Brak dba\u0142o\u015bci o czytelno\u015b\u0107 kodu:<ul><li>Z\u0142e nazewnictwo.<\/li><li>Zbyt d\u0142ugie funkcje\/metody.<\/li><\/ul><\/li><li>Niepoprawne funkcje\/metody:<ul><li>Przyjmowanie\/zwracanie nulli z metod zamiast opakowa\u0144 zwracanych typ\u00f3w w Optionale \u2013 k\u0142amanie na poziomie kodu innych programist\u00f3w.<\/li><\/ul><\/li><li>Niepoprawne dopasowanie wyj\u0105tk\u00f3w do warstwy aplikacji, np. IOException znajduje si\u0119 w warstwie biznesowej, restowej.<\/li><li>Brak programowania przez kontrakty.<\/li><li>Stosowanie mutowanych obiekt\u00f3w, kt\u00f3re mo\u017cna zast\u0105pi\u0107 niemutowanymi.<\/li><li>Stosowanie statycznych p\u00f3l, klas, metod w nieodpowiedni spos\u00f3b.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wzorce projektowe<\/strong><\/h2>\n\n\n\n<p>Nale\u017cy pami\u0119ta\u0107, \u017ce znajomo\u015b\u0107 wzorc\u00f3w projektowych do refaktoryzacji nie wystarczy. Wzorce s\u0105 jedynie otoczk\u0105, kt\u00f3r\u0105 widzimy, co r\u00f3wnie\u017c jest bardzo wa\u017cne. Mo\u017cna powiedzie\u0107, \u017ce <strong>wzorce s\u0105 realizacj\u0105 za\u0142o\u017ce\u0144 opisanych powy\u017cej<\/strong>, co mo\u017cna \u0142atwo zaobserwowa\u0107 na przyk\u0142adzie wzorca Proxy.<\/p>\n\n\n\n<p>Mo\u017cemy sobie wyobrazi\u0107, \u017ce mamy metod\u0119 o nazwie transferFunds. Obs\u0142uguje ona przelew mi\u0119dzy dwoma kontami zgodnie z logik\u0105 biznesow\u0105. Jednak w przypadku takiej metody bardzo cz\u0119sto mo\u017ce si\u0119 zdarzy\u0107, \u017ce musimy otworzy\u0107, zamkn\u0105\u0107 transakcje, sprawdzi\u0107 jakie\u015b regu\u0142y bezpiecze\u0144stwa, zalogowa\u0107, \u017ce nast\u0105pi\u0142 przelew. Nagle okazuje si\u0119, \u017ce nazwa metody nie odpowiada temu, co w \u015brodku si\u0119 dzieje. Mamy nadu\u017cycie, przedobrzenie, robimy wi\u0119cej ni\u017c powinni\u015bmy. M\u00f3wi\u0105c dosadniej, to k\u0142amiemy ju\u017c na etapie nazwy metody.<\/p>\n\n\n\n<p>Aby tego unikn\u0105\u0107, nale\u017cy dokona\u0107 separacji odpowiedzialno\u015bci, opakowa\u0107 kod poprzez ustanowienie po\u015brednika \u2013 Proxy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Przyk\u0142ady grup najcz\u0119\u015bciej spotykanych wzorc\u00f3w projektowych z kr\u00f3tkim opisem<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Kreacyjne \u2013 pokazuj\u0105 spos\u00f3b tworzenia metod, klas oraz typ\u00f3w danych.<ul><li>Singleton,<\/li><li>Builder,<\/li><li>Factory.<\/li><\/ul><\/li><li>Strukturalne \u2013 zale\u017cno\u015bci powi\u0105zanych ze sob\u0105 obiekt\u00f3w.<ul><li>Decorator,<\/li><li>Proxy (pe\u0142nomocnik),<\/li><li>Facade,<\/li><li>Chain of Responsibility.<\/li><\/ul><\/li><li>Behawioralne \u2013 zachowania wsp\u00f3\u0142pracuj\u0105cych obiekt\u00f3w.<ul><li>Visitor,<\/li><li>Observer,<\/li><li>Strategy,<\/li><li>Adapter.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>Przyk\u0142ady z dok\u0142adniejszym opisaniem <a href=\"https:\/\/java-design-patterns.com\/patterns\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >wzorc\u00f3w projektowych.<\/a><\/p>\n\n\n\n<p>Na koniec zach\u0119cam Was do zrobienia <a href=\"https:\/\/github.com\/ArticleAboutRefactoring\/ConvertingIfologyToEnum\/tree\/main\/src\/main\/java\/pl\/training\/movies\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >zadania b\u0119d\u0105cego samodzieln\u0105 pr\u00f3b\u0105 refaktoringu<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u0179r\u00f3d\u0142a<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li>Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck<\/li><li><a aria-label=\" (opens in a new tab)\" href=\"\/Users\/kwieczorek2\/Downloads\/bykowski.pl\/wzorce-projektowe\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >bykowski.pl\/wzorce-projektowe<\/a><\/li><li><a aria-label=\" (opens in a new tab)\" href=\"\/Users\/kwieczorek2\/Downloads\/Sourcemaking.com\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Sourcemaking.com<\/a><\/li><li><a aria-label=\" (opens in a new tab)\" href=\"\/Users\/kwieczorek2\/Downloads\/refactoring.guru\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >refactoring.guru<\/a><\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p><a href=\"#_ednref1\" id=\"_edn1\" rel=\"nofollow\" >[i]<\/a> podstawowych zasad, kt\u00f3rymi nale\u017cy si\u0119 kierowa\u0107 podczas programowania obiektowo. Skr\u00f3t pochodzi od pierwszych liter poszczeg\u00f3lnych zasad, s\u0105 to: single responsibility, open\/closed, liskov substitution, interface segregation oraz dependency inversion<\/p>\n\n\n\n<p><a href=\"#_ednref2\" id=\"_edn2\" rel=\"nofollow\" >[ii]<\/a> keep it simple stupid &#8211; nasz kod powinien by\u0107 tworzony i utrzymany w taki spos\u00f3b, aby by\u0142 dla wszystkich jak najbardziej zrozumia\u0142y i jasny<\/p>\n\n\n\n<p><a href=\"#_ednref3\" id=\"_edn3\" rel=\"nofollow\" >[iii]<\/a> tell don\u2019t ask \u2013 zasada m\u00f3wi o konkretnym podziale obowi\u0105zk\u00f3w pomi\u0119dzy naszymi klasami i obiektami, a ich zadaniami<\/p>\n\n\n\n<p><a id=\"_edn4\" href=\"#_ednref4\" rel=\"nofollow\" >[iv]<\/a> you ain\u2019t gonna need it \u2013 zasada m\u00f3wi, \u017ce w naszym programie powinni\u015bmy umieszcza\u0107 najistotniejsze funkcjonalno\u015bci, kt\u00f3re w danej chwili b\u0119d\u0105 nam potrzebne<\/p>\n\n\n\n<p><a href=\"https:\/\/sii.pl\/blog\/wp-admin\/post.php?post=21644&amp;action=edit#_ednref1\" class=\"ek-link\">[v]<\/a> don\u2019t repeat yourself \u2013 nale\u017cy unika\u0107 powtarzania tych samych cz\u0119\u015bci kodu w r\u00f3\u017cnych miejscach<\/p>\n\n\n\n<p>***<\/p>\n\n\n\n<p>Je\u017celi temat refaktoryzacji jest dla Ciebie interesuj\u0105cy, polecamy r\u00f3wnie\u017c inny artyku\u0142 naszego eksperta: <a href=\"https:\/\/sii.pl\/blog\/podejscie-do-refaktoryzacji-w-projekcie-ze-starymi-technologiami\/?category=development-na-miekko&amp;tag=architektura-it,legacy-code,refaktoryzacja\" target=\"_blank\" aria-label=\"Podej\u015bcie do refaktoryzacji w projekcie ze starymi technologiami (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\">Podej\u015bcie do refaktoryzacji w projekcie ze starymi technologiami<\/a><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;21644&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;27&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 27)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Rozw\u00f3j oprogramowania \u2013 refaktoryzacja&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 27)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Poj\u0119cie refaktoryzacji mo\u017ce by\u0107 interpretowane dwojako. Z jednej strony mo\u017ce by\u0107 rozumiane jako czynno\u015b\u0107 \u00ad\u2013 czasownik. Wtedy przez refaktoryzacj\u0119 rozumiemy &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/rozwoj-oprogramowania-refaktoryzacja\/\">Continued<\/a><\/p>\n","protected":false},"author":512,"featured_media":21657,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":7,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[2427,560,1178],"class_list":["post-21644","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-digital","tag-architektura-it","tag-refaktoryzacja"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/05\/Rozwoj-oprogramowania-\u2013-refaktoryzacja.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21644"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/512"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=21644"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21644\/revisions"}],"predecessor-version":[{"id":21664,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/21644\/revisions\/21664"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/21657"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=21644"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=21644"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=21644"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}