View
76
Download
0
Category
Preview:
Citation preview
Od codziennej higieny kodu
do strategicznejrefaktoryzacji
@MichalBartyzelblog.gettingThingsProgrammed.pl
Kod, który czyta się jak książkę
#CodeSpeaks2U
Tell, Don’t Ask
#CodeReadability
Samodokumentujący się kod
Kluczem do #softwareCraftsmanship są umiejętności lingwistyczne
Nazywanie
Co można zrobić z…
Zwiększamy efektywność zespołów projektowych4
Listą pracowników Ewidencją pracowników• Dodać pracownika• Usunąć pracownika• Usunąć wszystkich
pracowników
• Wciągnąć pracownika do ewidencji
• Wyciągnąć kartotekę pracownika• Oznaczyć urlop• Oznaczyć zwolnienie chorobowe• Wyciągnąć świadectwo pracy
Programujesz to, co nazywaszZwiększamy efektywność zespołów projektowych5
List<Employee> employees...
//...
EmployeeFile employeeFile = findEmployeeFile( personalID );
employeeFile.getEmergencyContactInformation();
A potem powstaje architektura Zwiększamy efektywność zespołów projektowych6
List<Employee> employees...
//...
EmployeeFile employeeFile = findEmployeeFile( personalID );
employeeFile.getEmergencyContactInformation();
I dzieją się z nią dziwne rzeczyZwiększamy efektywność zespołów projektowych7
Co chcemy zacząć zauważać?
Zwiększamy efektywność zespołów projektowych8
Nazwa klasy cLOC
LocationManager 26 752
NetworkItem 10 955
TransferOperations 6 871
CalculatorsManager 4 325
MonitorManager 1 514
VTViewInvoker 48
ContactService 47
Address 34
DataRange 21
LoggedUserDetailsModel 13
Zwiększamy efektywność zespołów projektowych9
Zwiększamy efektywność zespołów projektowych10
Zwiększamy efektywność zespołów projektowych11
Klasy
Zwiększamy efektywność zespołów projektowych12
Konwencje
Zwiększamy efektywność zespołów projektowych13
Metody
Extract Method?
ZmienneZwiększamy efektywność zespołów projektowych14
Zwiększamy efektywność zespołów projektowych15
Axel Fontaine, Architecting for Continuous Deliveryhttp://2013.33degree.org/talk/show/51
Pakiety
Biznes ARCH Klasy Metody Zmienne
Smell Zmienna quasi-globalna
Przykład
Refaktor.
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych16
Biznes ARCH Klasy Metody Zmienne
Smell Zmienna quasi-globalna
Przykład tmp1, tmp2, tmp3
Refaktor.
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych17
Biznes ARCH Klasy Metody Zmienne
Smell Zmienna quasi-globalna
Przykład tmp1, tmp2, tmp3
Refaktor. Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych18
Biznes ARCH Klasy Metody Zmienne
Smell Long Method Zmienna quasi-globalna
Przykład tmp1, tmp2, tmp3
Refaktor. Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych19
Biznes ARCH Klasy Metody Zmienne
Smell Long Method Zmienna quasi-globalna
Przykład process, performOperation
tmp1, tmp2, tmp3
Refaktor. Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych20
Biznes ARCH Klasy Metody Zmienne
Smell Long Method Zmienna quasi-globalna
Przykład process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych21
Biznes ARCH Klasy Metody Zmienne
Smell God Class Long Method Zmienna quasi-globalna
Przykład process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych22
Biznes ARCH Klasy Metody Zmienne
Smell God Class Long Method Zmienna quasi-globalna
Przykład LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych23
Biznes ARCH Klasy Metody Zmienne
Smell God Class Long Method Zmienna quasi-globalna
Przykład LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych24
Biznes ARCH Klasy Metody Zmienne
Smell Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych25
Biznes ARCH Klasy Metody Zmienne
Smell Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych26
Biznes ARCH Klasy Metody Zmienne
Smell Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Wprowadź wzorzec architektoniczny
Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych27
Biznes ARCH Klasy Metody Zmienne
Smell Sexy Vision Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Wprowadź wzorzec architektoniczny
Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych28
Biznes ARCH Klasy Metody Zmienne
Smell Sexy Vision Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład ZSI, BI, DW Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Wprowadź wzorzec architektoniczny
Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych29
Biznes ARCH Klasy Metody Zmienne
Smell Sexy Vision Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład ZSI, BI, DW Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Zdefiniuj, podziel, zmień proces
Wprowadź wzorzec architektoniczny
Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych30
Biznes ARCH Klasy Metody Zmienne
Smell Sexy Vision Big Ball of Mudhttp://laputan.org/mud/
God Class Long Method Zmienna quasi-globalna
Przykład ZSI, BI, DW Genreic Plugin Framework,Multi-Device Platform
LocationManager, NetworkItem
process, performOperation
tmp1, tmp2, tmp3
Refaktor. Zdefiniuj, podziel, zmień proces
Wprowadź wzorzec architektoniczny
Extract Classhttp://refactoring.com
Extract Methodhttp://refactoring.com
Split Temporary Variable http://refactoring.com
Brak umiejętności nazywaniaZwiększamy efektywność zespołów projektowych31
#odpowiedzialność to rola/zadanie wyrażone nazwą
#dobraNazwa przychodzi z czasem
Kryterium czytelności kodu: #testIvony
Code Speaks 2U
public void add(Object element) { if (!readOnly) { int newSize = size + 1; if (newSize > elements.length) { Object[] newElements; newElements = new Object[elements.length + 10]; for (int i = 0; i < size; i++) { newElements[i] = elements[i]; } elements = newElements; } elements[size++] = element; }}
public void add(Object element) {
if (readOnly) { return; } if (atCapacity()) { grow(); } addElement(element);}
#CleanCode• Umieszczaj intencje w nazwach• Uwidaczniaj różnice• Stosuj nazwy, które da się wymówić• Unikaj dowcipnych nazw• Dbaj o pojedynczą odpowiedzialność• Unikaj dużej liczby parametrów• Stosuj Command-Query Separation• …
for (int dataType : types) { if (RowManagerHelper.isRawDataTypeCalculated( data, type.getType())) types.add(dataType); else { ID id = RowManagerHelper.getID(data, type, enType,
obj.getGroup().useDeprecatedXmlFiles()); if (id != null) { ids.add(id); if (id.getValue() != null) { IDFactory f = IDProviderFactory.getInstance()
.createProvider(pObj, element); list_id.addAll(idProvider.getAllIDs(id, 0)); } for (int j = i; j < (list_oid.size()); j++) { mapDaType.put(j, data); } i = list_id.size(); } }
Zwiększamy efektywność zespołów projektowych39
public long insertDepartment (String CusId,String Employee, String FullName,String LastName,String FirstName,String PESEL, String ERProvince,String ERZipCode,String ERCountry, String ERStreetName,String ERBuildingNumber,String ERNumber, String ERPostOffice,String EmailAddress,String SMSNo, String CallNbr,String Status, String IStatus,String SMSStat, String WEBs, String XMLStatus,String BIStatus, String queue, String DasFlag, Date DateBirth,boolean bGenerate,String TAddress, String TCity,String sex,String Nationality,String NIP, Object Profile, String DefaultAccount, Sring address, String ADCity, String ADProvince, String ADZipCode, String ADCountry,String ADStreetName,String Number, String ADFlatNumber,String ADPostOffice,String ERAddress, String ERCity, String DProvince,String TZipCode,String TCountry, String TStreetName, String TBuildingNumber, String DFlatNumber, String TPostOffice, String PersonalId, String PassportNo) throws GenericException {
//...
public class LDW_LocationCommonManager extends LDW_BaseService implements LDW_ILocationCommonManager {
private TStruct oTStruct;private TypeData oTypeData;private SolSubject _Subject;private SolUniqueSubject _UniqueSubject;private SolUniqueSubjectExcep _UniqueSubjectExcep;private SolCommunAddress _CommunAddress;private SolAddress _Address;private SolTransactions _Transactions;private SolStatusChanl _StatusChan;private UserContext uC;private UserContext_LDW uC_LDW;private SOLSegmentsUser _SegmentsUser;private LDWA_ISecurityString _oSecurity;private String _zoSdTransitionDate;private String _sSType;private String _zoInterimPasswordMask="";private String _zoInterimPassNoMasked="";private String _zoInterimPassMasked="";private Date _zoMigrationDate;private String _zoMigrationStage="";public int _iMigrationStage;
//...
Zwiększamy efektywność zespołów projektowych40
if (!r.IsDataRangeDoNull() && !r.IsDataRangeOdNull() && ((r.DataRangeOd.Day != yearRow.Miesiac.Day && r.DataRangeOd.Day != yearRow.Miesiac.AddMonths(1).Day) || (r.DataRangeDo.Day != yearRow.Miesiac.Day && r.DataRangeDo.Day != yearRow.Miesiac.AddMonths(1).Day)))
//...
Zwiększamy efektywność zespołów projektowych41
if (cardId == null) throw new NullPointerException(
"cardId is null");
if (cardId.getCardNo() == null) throw new NullPointerException(
"card in cardNo is null");
if (cardId.getCardNo().getCardNoId() == null) throw new NullPointerException(
"cardNoId is null");
Zwiększamy efektywność zespołów projektowych42
#testIvony Posłuchaj czytanego kodu:
1. Zrozumiałe -> czytelny2. Niezrozumiałe -> nieczytelny
#nieczytelny
• Próbujesz rozwiązać zagadkę logiczną
• Powtarzasz kod w myślach
• Zaczynasz mówić na głos
#czytelny
• Wyobrażasz sobie historię, która się dzieje
• Zupełnie jak w książce!
Zwiększamy efektywność zespołów projektowych44
if ("".equals(m_Action) || "Cancel".equalsIgnoreCase(m_sAction) {
if ( actionCancelled( m_sAction ) ) {
#uwazneKomentowanie
#scaffoldingRefactoring
1. Dodaj tymczasowe komentarze2. Nazwij warunki logiczne3. Pogrupuj zmienne leniwie4. Popraw wrażenia wizualne
#NCR Natural Course of Refactoring: an intuitive #refactoringWorkflow #continuousRefactoring
Natural Course of Refactoring®
#smell Spaghetti Code`#book Clean Code, Code Complete
#smell Long Method
#book Implementation Patterns
#smell God Class
#book Refactoring
#smell Duplicated Code
#book Design Pattern
#smell Big Bull of Mud
#book POSA, PoEAA, DDD
#smell Architectural Drift
#res blogi, konferencje, listy
#everydayRefactoring
#strategicRefactoring
Niektóre fragmenty kodu zawsze będą cuchnąć. Naucz się z tym żyć #codeSmell
Refaktoryzować?
High complexity/
Seldom changes
Don’t touch it.
High complexity/ Frequent changes
Apply strategic refactoring
Low complexity/ Seldom changes
Utils, good for experiments
Low complexity/Frequen
t changes
Heaven
Strategiczna refaktoryzacja54
Confront with:• team opinions
• business strategy
Frequency of changes
Complexity
Core Domain?
Core Domain
1 programista, 6 miesięcy, PHP
Nową funkcjonalność rozwijaj osobno w powiązanym kontekście
Strategiczna refaktoryzacja58
Bubble Context
#refaktoryzacja to przede wszystkim wyzwanie organizacyjne, a nie techniczne #strategicRefactoring
Zarządzanie
#Action30• Nordea Bank AB rozwija eBankowość w
krajach bałtyckich• Biznes długo czeka na zlecone
funkcjonalności (do kilku miesięcy)
#cel Skrócić czas stworzenia nowej funkcjonalności do 30 dni
…a o co chodzi?
Nazwij problemy• Specjalizacja programistów• Multitasking• Duża ilość nieużywanego kodu• Leciwe technologie• Nadwyrężona odpowiedzialność widoków• Nieefektywne spotkania
Mierz, co się da
Pisz raporty• Redukcja wierszy kodu o 3%• Redukcja CC o 15%
Dla tej próbki kodu można by wykonać 29 testów mniej
– aproksymując po całym kodzie…• przeliczając wykonane testy na dni robocze…
Włączaj ludzi• Kierownicy projektów proszą o więcej• Management zainteresowany Action-30• Programiści z innych zespołów
przyłączają się do inicjatywy• Wsparcie od całego managementu i top
managementu
#refaktoryzacja sprawia kłopoty, bo robisz zbyt wiele rzeczy na raz
Małe kroki
Programowanie jest #fajne
//TODO: Wczytaj plik CSV
public String[][] readCSV(String filePath );
Pojawił się błąd w bazie…
To pewnie w serwisie…
albo w widoku…
albo w konfigu…
albo w konfigu…
Zasada zaangażowania
Przyczyna błędu tkwi w…• Czyimś kodzie• Braku dostępu do usługi• Niejednoznacznych wymaganiach• Niewłaściwym przetestowaniu• Bibliotece• Słabej jakości kodzie oddziedziczonym • …
DUŻE KROKI to Odczucie ***
Najlepsze strategie skutecznych programistów
77Technika Małych Kroków
Krok := zmiana/dodanie instrukcji
Najlepsze strategie skutecznych programistów
78Technika Małych Kroków
Małe Kroki w refaktoryzacji
Uważne komentowanieZmiany nazwLeniwe przestawianie zmiennychPrzyrostowe odtwarzanie testów
?
• ~500 dni szkoleniowych
• 80+ klientów: Agora, Grupa Allegro, ING Usługi Finansowe, Lufthansa Systems Polska, Nokia Siemens Networks, Opera Software, Samsung R&D Institute Poland, Nordea Bank AB (…)
• 8 projektów związanych ze zwinną transformacją
• 40+ artykułów w prasie branżowej
• 3 książki
@MichalBartyzelSzkoła Agile - Planowanie by Michał Bartyzel80
enxoo bootcamp
https://goo.gl/9yZnY8
Skuteczna komunikacja to taka sama umiejętność jak jazda samochodem czy programowanie. Michał Bartyzel doskonale to pokazuje, rozkładając cały proces rozmowy na proste elementy. Dzięki temu czytelnik może nauczyć się rozpoznawać wzorce i dopasowywać odpowiednie techniki do kontekstu rozmowy. Autor posługuje się prostym i zrozumiałym językiem, uważnie wybiera najważniejsze aspekty tematów z pogranicza psychologii i coachingu. Narzędzia, które czytelnik dostaje do ręki, można od razu wykorzystać w pracy.
Krystian Kaczor, Agile Coach
enxoo bootcamp
https://goo.gl/XfSLPQ
Sprawne sterowanie swoją uwagą, planowanie zadań czy umiejętność ich oszacowania to wiedza, której brakuje większości programistów. Często nie zdajemy sobie nawet sprawy z istnienia problemów spowalniających naszą pracę.W niniejszej książce Autor przedstawia bogaty wachlarz wyzwań stojących przed świadomym programistą. Nie poprzestaje na tym: wysuwa propozycje samodoskonalenia. Opisuje sprawdzone recepty pomagające zrozumieć codzienne problemy, rozbija je na czynniki pierwsze i przygotowuje do walki o lepszą organizację czasu.
Maciej Aniserowicz, twórca bloga devstyle.pl
enxoo bootcamp
https://goo.gl/dXkfLS
This book includes a set of out-and-dried techniques for improving your cooperation with the business. The main goal of this publication is to give you two key skills: discovering the business needs, and managing the conversation in a way that will enable you to collect precise and useful information. First and foremost, I promote the first point of the Agile Manifesto: “Individuals and interactions over processes and tools.” Thus, if you tend to think that your clients do not know what they want, this book is exactly for you.
gettingThingsProgrammed.evenea.pl
Architectural Kata• Zobacz program warsztatu
– https://biturl.io/VK4j52
• Zobacz fragment warsztatu– https://biturl.io/VK4Vn8
• Zobacz efekt warsztatu– https://biturl.io/VK4ai0
enxoo bootcamp
Sprawdź najbliższe szkolenia otwarte# Nowoczesne architektury aplikacji
# Getting Things Programmed# Architektura aplikacji biznesowych# Zbieranie wymagań i współpraca z klientem# Techniki pracy z kodem# Technical Leadership™
więcej na bnsit.pl/szkolenia-otwarte
Recommended