61
We design and develop complex business applications

Object Calisthenics (ZOSIA, Przesieka 2017 PL)

Embed Size (px)

Citation preview

Page 1: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

We design and developcomplex business applications

Page 2: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Object Calisthenics

czyli jak uczynić nasz kod czytleniejszym

Grzegorz Byrka

ZOSIA 2017

Page 3: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Dlaczego warto pisać kod dobrej jakości? (poza tym, że nam za to płacą)

3

Page 4: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Poprawa czytelności i zrozumiałości

• Ułatwione wdrażanie nowych osób do zespołu• Łatwiejsze zarządzanie i modyfikowanie istniejących funkcjonalności

Dlaczego warto pisać kod dobrej jakości?

4

Page 5: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Poprawa czytelności i zrozumiałości

• Ułatwione wdrażanie nowych osób do zespołu• Łatwiejsze zarządzanie i modyfikowanie istniejących funkcjonalności

● Zmniejszona potrzeba tworzenia dokumentacji technicznej

• Z wyłączeniem dokumentowania administracji systemem

Dlaczego warto pisać kod dobrej jakości?

5

Page 6: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Poprawa czytelności i zrozumiałości

• Ułatwione wdrażanie nowych osób do zespołu• Łatwiejsze zarządzanie i modyfikowanie istniejących funkcjonalności

● Zmniejszona potrzeba tworzenia dokumentacji technicznej

• Z wyłączeniem dokumentowania administracji systemem

● Łatwiejsze testowanie

Dlaczego warto pisać kod dobrej jakości?

6

Page 7: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Poprawa czytelności i zrozumiałości

• Ułatwione wdrażanie nowych osób do zespołu• Łatwiejsze zarządzanie i modyfikowanie istniejących funkcjonalności

● Zmniejszona potrzeba tworzenia dokumentacji technicznej

• Z wyłączeniem dokumentowania administracji systemem

● Łatwiejsze testowanie

● Poprawiona reużywalność poszczególnych metod

Dlaczego warto pisać kod dobrej jakości?

7

Page 8: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

DISCLAIMER

8

Przedstawione zasady mają charakter zaleceń,należy dostosować je do natury własnego projektu

Page 9: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Zasady Object Calisthenics

9

Page 10: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

Zasady Object Calisthenics

10

Page 11: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Board { String board() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { buf.append(data[i][j]); buf.append("\n"); } } return buf.toString(); }}

11

Page 12: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Board { String board() { // 0 StringBuffer buf = new StringBuffer(); for (int i = 0; i < 10; i++) { // 1 for (int j = 0; j < 10; j++) { // 2 buf.append(data[i][j]); buf.append("\n"); } } return buf.toString(); }}

12

Page 13: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Board { String board() { StringBuffer buf = new StringBuffer(); collectRows(buf); return buf.toString(); }

void collectRows(StringBuffer buf) { for (int i = 0; i < 10; i++) { collectRow(buf, i); } }

void collectRow(StringBuffer buf, int row) { for (int i = 0; i < 10; i++) { Buf.append(data[row][i]); buf.append("\n"); } }}

13

Page 14: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Dokładniejsze nazewnictwo metod

● Krótsze metody

● Re-używalne metody

Zalety:

14

Page 15: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

Zasady Object Calisthenics

15

Page 16: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

if (…) { …} elseif (…) { …} elseif (…) { …} elseif (…) { …} elseif (…) { …} elseif (…) { …} elseif (…) { …} elseif (…) { …} else { …}

16

Page 17: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

17

Page 18: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

public void login(String username, String password) { if (userRepository.isValid(username, password)) { redirect("homepage"); } else { addFlash("error", "Bad credentials"); redirect("login"); }}

18

Page 19: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

public void login(String username, String password) { if (userRepository.isValid(username, password)) { return redirect("homepage"); }

addFlash("error", "Bad credentials"); return redirect("login");}

19

Page 20: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

public void login(String username, String password) { String redirectRoute = "homepage";

if (!userRepository.isValid(username, password)) { addFlash("error", "Bad credentials"); redirectRoute = "login"; }

redirect(redirectRoute);}

20

Page 21: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Mniej upakowany kod

● Mniejsza złożoność logiczna

● Czytelność

● Unikamy duplikowania kodu

Zalety:

21

Page 22: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

Zasady Object Calisthenics

22

Page 23: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Class Date { public boolean check(int year, int month, int day){ ... }}

// 9th of October or 10th of SeptemberDate.check(2017, 10, 9);

23

Page 24: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Class Date { public boolean check(Year year, Month month, Day day){ ... }}

Date.check(new Year(2017), new Month(10), new Day(9));

24

Page 25: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Zabezpieczenie przed niewykryciem błędnego użycia metody

● Type hinting

Zalety:

25

Page 26: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

Zasady Object Calisthenics

26

Page 27: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

– Każda kolekcja musi być opakowana w swoją klasę, która będzie odpowiedzialna za wszystkie operacje

związane z tą kolekcją (filtrowanie, mapowanie, łączenie kolekcji, … )

Zasady Object Calisthenics

27

Page 28: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

– Każda kolekcja musi być opakowana w swoją klasę, która będzie odpowiedzialna za wszystkie operacje

związane z tą kolekcją (filtrowanie, mapowanie, łączenie kolekcji, … )

– Żadna klasa z kolekcją nie może zawierać innych zmiennych

Zasady Object Calisthenics

28

Page 29: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię (lub –> w PHP)

Zasady Object Calisthenics

29

Page 30: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Piece { public String representation;}

class Location { public Piece current;}

class Board { public String boardRepresentation() { StringBuilder buf = new StringBuilder();

for (Location loc : squares()) { buf.append(loc.current.representation.substring(0, 1)); }

return buf.toString(); }}

30

Page 31: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Piece { private String representation;

public String character() { return representation.substring(0, 1); }

public void addTo(StringBuilder buf) { buf.append(character()); }}

31

Page 32: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Piece { private String representation;

public String character() { return representation.substring(0, 1); }

public void addTo(StringBuilder buf) { buf.append(character()); }}

class Location { private Piece current;

public void addTo(StringBuilder buf) { current.addTo(buf); }}

32

Page 33: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Piece { private String representation;

public String character() { return representation.substring(0, 1); }

public void addTo(StringBuilder buf) { buf.append(character()); }}

class Location { private Piece current;

public void addTo(StringBuilder buf) { current.addTo(buf); }}

33

Page 34: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

class Piece { private String representation;

public String character() { return representation.substring(0, 1); }

public void addTo(StringBuilder buf) { buf.append(character()); }}

class Location { private Piece current;

public void addTo(StringBuilder buf) { current.addTo(buf); }}

34

class Board { public String boardRepresentation() { StringBuilder buf = new StringBuilder();

for (Location location : squares()) { location.addTo(buf); }

return buf.toString(); }}

Page 35: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Przestrzeganie zasad prywatności

● Zgodność z Prawem Demeter (regułą ograniczonej interakcji: „Rozmawiaj tylko z bliskimi przyjaciółmi”)

Zalety:

35

Page 36: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

Zasady Object Calisthenics

36

Page 37: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

if (sx >= sy) { if (sx > strSysMatImgW) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; } if (ny > strSysMatImgH) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; }} else { if (sy > strSysMatImgW) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; } if (nx > strSysMatImgH) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; }} 37

Page 38: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

if (sx >= sy) { if (sx > strSysMatImgW) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; } if (ny > strSysMatImgH) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; }} else { if (sy > strSysMatImgW) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; } if (nx > strSysMatImgH) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; }} 38

Page 39: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

if (sx >= sy) { if (sx > strSysMatImgW) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; } if (ny > strSysMatImgH) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; }} else { if (sy > strSysMatImgH) { nx = strSysMatImgH * sx / sy; ny = strSysMatImgH; } if (nx > strSysMatImgW) { ny = strSysMatImgW * sy / sx; nx = strSysMatImgW; }} 39

Page 40: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

Zasady Object Calisthenics

40

Page 41: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

– Nazwy powinny być na tyle precyzyjne, by jednoznacznie dało się tylko po niej stwierdzić, za co

odpowiada klasa, metoda, bądź zmienna

Zasady Object Calisthenics

41

Page 42: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

– Nazwy powinny być na tyle precyzyjne, by jednoznacznie dało się tylko po niej stwierdzić, za co

odpowiada klasa, metoda, bądź zmienna

– Gdy nie umiesz wymyślić adekwatnej nazwy klasy, zastanów się, czy ta klasa ma sens w ogóle

Zasady Object Calisthenics

42

Page 43: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Czytelność i ułatwione zarządzanie kodem

● Okazja do wykrycia problemów z architekturą systemu

● Wykorzystanie wsparcia IDE do podpowiadania (i wyszukiwania) nazw

Zalety:

43

Page 44: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

Zasady Object Calisthenics

44

Page 45: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

– Maksymalnie 50 linii na metodę w klasie

Zasady Object Calisthenics

45

Page 46: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

– Maksymalnie 50 linii na metodę w klasie

– Maksymalnie 10 metod w klasie

Zasady Object Calisthenics

46

Page 47: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

– Maksymalnie 50 linii na metodę w klasie

– Maksymalnie 10 metod w klasie

– Maksymalnie 15 klas w pakiecie

Zasady Object Calisthenics

47

Page 48: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

48

Page 49: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

8. Ogranicz ilość pól w klasie (Eng. Instance Variables) do 2 kilku

Zasady Object Calisthenics

49

Page 50: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

8. Ogranicz ilość pól w klasie (Eng. Instance Variables) do 2 kilku

Zasady Object Calisthenics

50

Page 51: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

8. Ogranicz ilość pól w klasie (Eng. Instance Variables) do 2 kilku

Zasady Object Calisthenics

51

Page 52: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Mniej zależności

● Opakowanie typów prostych

● Większa spójność

● Łatwiejsze mockowanie na potrzeby testów jednostkowych

Zalety:

52

Page 53: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

8. Ogranicz ilość pól w klasie (Eng. Instance Variables) do 2 kilku

9. Mów, nie pytaj (Unikaj GET’erów oraz SET’erów)

Zasady Object Calisthenics

53

Page 54: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

// Gameprivate int score;

public void setScore(int score) { this.score = score;}

public int getScore() { return score;}

// Usagegame.setScore(game.getScore() + ENEMY_DESTROYED_SCORE);

54

Page 55: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

// Gameprivate int score;

public void addScore(int delta) { this.score += delta;}

// Usagegame.addScore(ENEMY_DESTROYED_SCORE);

55

Page 56: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

// Gameprivate int score;

public void addScore(int delta) { this.score += delta;}

public int getScore() { return score;}

// Usagegame.addScore(ENEMY_DESTROYED_SCORE);

56

Page 57: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Logika klasy wewnątrz klasy – nie jest rozproszona po całym projekcie

Zalety:

57

Page 58: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

1. Tylko jeden poziom wcięcia na metodę

2. Unikaj używania ELSE

3. Opakowuj typy proste

4. Kolekcje jako osobne klasy

5. Jedna kropka na linię

6. Nie skracaj nazw

7. Klasy i metody muszą być małe

8. Ogranicz ilość pól w klasie (Eng. Instance Variables) do 2 kilku

9. Mów, nie pytaj

Zasady Object Calisthenics

58

Page 59: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Pytania ...

59

Page 60: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

● Rafael Dohms, Your code sucks, let's fix it (PHP Benelux, Antwerpia 2013)

● Guilherme Blanco, Object Calisthenics Applied to PHP (GTA Meetup, Toronto 2012)

● Paweł Lewtak, Object calisthenics (PHPCon, Rawa Mazowiecka 2016)

● http://williamdurand.fr/2013/06/03/object-calisthenics/

● https://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf

● http://williamdurand.fr/2012/01/24/designing-a-software-by-naming-things/

● http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html

● http://wiki.c2.com/?LawOfDemeter

Bibliografia:

60

Page 61: Object Calisthenics  (ZOSIA, Przesieka 2017 PL)

Dziękuję

61