Od codziennej higieny do strategicznej refaktoryzacji

Post on 05-Apr-2017

77 views 0 download

Transcript of Od codziennej higieny do strategicznej refaktoryzacji

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 &lt; (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