65
Abilitare l'agilità con il design semplice Mini IAD Vimercate 2017 Gabriele Tondi - @racingDeveloper

Abilitare l'agilità con il design semplice

Embed Size (px)

Citation preview

Page 1: Abilitare l'agilità con il design semplice

Abilitare l'agilità con il design

semplice

Mini IAD Vimercate 2017Gabriele Tondi - @racingDeveloper

Page 2: Abilitare l'agilità con il design semplice

public static Set<Coordinate> nextGeneration(Set<Coordinate> liveCells){ Set<Coordinate> nextGeneration = new HashSet<>();

for (Coordinate liveCell : liveCells) { Set<Coordinate> block = new HashSet<>(); for (int currentX1 = liveCell.x - 1; currentX1 <= liveCell.x + 1; currentX1++) { for (int currentY1 = liveCell.y - 1; currentY1 <= liveCell.y + 1; currentY1++) { block.add(new Coordinate(currentX1, currentY1));}}

block.remove(liveCell);

for (Coordinate currentCell : block) { int liveCellsCount = 0;

Set<Coordinate> currentBlock = new HashSet<>(); for (int currentX = currentCell.x - 1; currentX <= currentCell.x + 1; currentX++) { for (int currentY = currentCell.y - 1; currentY <= currentCell.y + 1; currentY++) { currentBlock.add(new Coordinate(currentX, currentY));}}

currentBlock.remove(currentCell); for (Coordinate coordinate : currentBlock) { if (liveCells.contains(coordinate)) { liveCellsCount++; }}

int aliveCells = liveCellsCount;

if (liveCells.contains(currentCell)) { if (aliveCells == 2 || aliveCells == 3) { nextGeneration.add(currentCell); }} else { if (aliveCells == 3) { nextGeneration.add(currentCell); }}}}

return nextGeneration;} A

Page 3: Abilitare l'agilità con il design semplice

public class World {

public World evolve() { Set<Cell> nextGeneration = nextGeneration = cells.stream() .map(cell -> cell .coordinate() .blockIncludeSelf()) .flatMap(coordinates -> coordinates .stream()) .map(coordinate -> evolveAt(coordinate)) .collect(toSet());

return new World(nextGeneration); }

private Cell evolveAt(Coordinate coordinate) { return cellAt(coordinate) .evolve(aliveNeighboursOf(coordinate)); }

private Cell cellAt(Coordinate coordinate) { return cells.stream() .filter(c -> c.isAt(coordinate)) .findFirst() .orElse(new DeadCell(coordinate)); }

public int aliveNeighboursOf(Coordinate c) { Set<Coordinate> block = c.block(); block.retainAll(aliveCellsCoordinates());

return block.size(); }

B

private Set<Cell> aliveCells() { return cells.stream() .filter(c -> c.isAlive()) .collect(toSet()); }

private Set<Coordinate> aliveCellsCoordinates() { return aliveCells().stream() .map(c -> c.coordinate()) .collect(toSet()); }}

public class AliveCell extends Cell { public Cell evolve(int aliveNeighboursCount){ // [...] }}

public class DeadCell extends Cell { public Cell evolve(int aliveNeighboursCount){ // [...] }}

public class Coordinate { public Set<Coordinate> block() { // [...] }

public Set<Coordinate> blockIncludeSelf(){ // [...] }}

Page 4: Abilitare l'agilità con il design semplice

Cosa cambia?

Page 5: Abilitare l'agilità con il design semplice

Struttura, ossia design.

Page 6: Abilitare l'agilità con il design semplice

Perché facciamo design?

Page 7: Abilitare l'agilità con il design semplice

Vanità?

Page 8: Abilitare l'agilità con il design semplice

Stile?

Page 9: Abilitare l'agilità con il design semplice

Arte?

Page 10: Abilitare l'agilità con il design semplice

NO!

Riduzione e controllo del costo del cambiamento

Page 11: Abilitare l'agilità con il design semplice

Cosa fareste?

tempo

cost

o ca

mbi

amen

to

Page 12: Abilitare l'agilità con il design semplice

Quanto ne sappiamo all'inizio?

Page 13: Abilitare l'agilità con il design semplice

Cosa fareste?

tempo

cost

o ca

mbi

amen

to

Quanto ne sappiamo?

Page 14: Abilitare l'agilità con il design semplice

design speculativo

assunzioni errateaumento costo cambiamento

per evitare di pagare un costo alto provo ad anticipare il

cambiamento

le speculazioni errate mi costano

per avere più possibilità di azzeccarci devo fare più

assunzioni!

Page 15: Abilitare l'agilità con il design semplice

Kent Beck spezza il ciclo a retroazione positiva

Page 16: Abilitare l'agilità con il design semplice

Prova a prevedere i cambiamenti ad un mese

Page 17: Abilitare l'agilità con il design semplice

...ad una settimana

Page 18: Abilitare l'agilità con il design semplice

...ad un giorno

Page 19: Abilitare l'agilità con il design semplice

...fino al momento stesso

Page 20: Abilitare l'agilità con il design semplice

4 regole del design semplice

Page 21: Abilitare l'agilità con il design semplice

Semplice? Il mio design è già semplice per me!

Page 22: Abilitare l'agilità con il design semplice

SempliceEtimologia:

lat. simplĭce(m), comp. di sem- ‘una volta’ e -plex, corradicale di plectĕre ‘intrecciare’ e plicāre ‘piegare’; propr. ‘intrecciato, piegato una sola volta’.

Definizione:

formato di un solo elemento

fonte: http://www.garzantilinguistica.it

Page 23: Abilitare l'agilità con il design semplice

FacileEtimologia:

lat. facĭle(m), deriv. di facĕre ‘fare’; propr. ‘che si fa, che è possibile fare’.

Definizione:

che si può fare senza difficoltà; agevole, comodo

che si ottiene con poca o senza fatica

fonte: http://www.garzantilinguistica.it

Page 24: Abilitare l'agilità con il design semplice

Facile è soggettivo

Page 25: Abilitare l'agilità con il design semplice

Semplice è oggettivo

Page 26: Abilitare l'agilità con il design semplice

Ci serve un metro per misurare in maniera oggettiva il design

Page 27: Abilitare l'agilità con il design semplice

Il design semplice:1. passa tutti i test

2. esprime l'intento

3. non contiene duplicazione

4. viene realizzato con il minor numero di elementi possibili

Page 28: Abilitare l'agilità con il design semplice

L'ordine conta

Page 29: Abilitare l'agilità con il design semplice

Il design semplice:

1. passa tutti i test

2. esprime l'intento

3. non contiene duplicazione

4. viene realizzato con il minor numero di elementi possibili

PRIORITÀ

+-

Page 30: Abilitare l'agilità con il design semplice

1. passa tutti i test

2. esprime l'intento

3. non contiene duplicazione

4. viene realizzato con il minor numero di elementi possibili

Page 31: Abilitare l'agilità con il design semplice

Devo poter verificare rapidamente i cambiamenti

Page 32: Abilitare l'agilità con il design semplice

Ah, quindi deve essere testabile!

Page 33: Abilitare l'agilità con il design semplice

1. passa tutti i test

2. esprime l'intento

3. non contiene duplicazione

4. viene realizzato con il minor numero di elementi possibili

Page 34: Abilitare l'agilità con il design semplice

Non è solo questione di naming (variabili, metodi privati etc)

Page 35: Abilitare l'agilità con il design semplice

Cos'è l'intento?

public List<Customer> selectWhereNameLike(String name)

public List<Customer> searchByName(String name)

Page 36: Abilitare l'agilità con il design semplice

Cos'è l'intento?

public void sendMailUsingSmtp(MailMessage message)

public void sendMessage(Message message)

Page 37: Abilitare l'agilità con il design semplice

Intento: cosa fa, non come lo fa!

Page 38: Abilitare l'agilità con il design semplice

Intento => Astrazione

Page 39: Abilitare l'agilità con il design semplice

Le astrazioni riducono l'accoppiamento

Page 40: Abilitare l'agilità con il design semplice

1. passa tutti i test

2. esprime l'intento

3. non contiene duplicazione

4. viene realizzato con il minor numero di elementi possibili

Page 41: Abilitare l'agilità con il design semplice

public static Set<Coordinate> nextGeneration(Set<Coordinate> liveCells){ Set<Coordinate> nextGeneration = new HashSet<>();

for (Coordinate liveCell : liveCells) { Set<Coordinate> block = new HashSet<>(); for (int currentX1 = liveCell.x - 1; currentX1 <= liveCell.x + 1; currentX1++) { for (int currentY1 = liveCell.y - 1; currentY1 <= liveCell.y + 1; currentY1++) { block.add(new Coordinate(currentX1, currentY1));}}

block.remove(liveCell);

for (Coordinate currentCell : block) { int liveCellsCount = 0;

Set<Coordinate> currentBlock = new HashSet<>(); for (int currentX = currentCell.x - 1; currentX <= currentCell.x + 1; currentX++) { for (int currentY = currentCell.y - 1; currentY <= currentCell.y + 1; currentY++) { currentBlock.add(new Coordinate(currentX, currentY));}}

currentBlock.remove(currentCell);

for (Coordinate coordinate : currentBlock) { if (liveCells.contains(coordinate)) { liveCellsCount++; }}

int aliveCells = liveCellsCount;

if (liveCells.contains(currentCell)) { if (aliveCells == 2 || aliveCells == 3) { nextGeneration.add(currentCell); }} else { if (aliveCells == 3) { nextGeneration.add(currentCell); }}}}

return nextGeneration;}

Page 42: Abilitare l'agilità con il design semplice

public static Set<Coordinate> nextGeneration(Set<Coordinate> liveCells){ Set<Coordinate> nextGeneration = new HashSet<>();

for (Coordinate liveCell : liveCells) { Set<Coordinate> block = new HashSet<>(); for (int currentX1 = liveCell.x - 1; currentX1 <= liveCell.x + 1; currentX1++) { for (int currentY1 = liveCell.y - 1; currentY1 <= liveCell.y + 1; currentY1++) { block.add(new Coordinate(currentX1, currentY1));}}

block.remove(liveCell);

for (Coordinate currentCell : block) { int liveCellsCount = 0;

Set<Coordinate> currentBlock = new HashSet<>(); for (int currentX = currentCell.x - 1; currentX <= currentCell.x + 1; currentX++) { for (int currentY = currentCell.y - 1; currentY <= currentCell.y + 1; currentY++) { currentBlock.add(new Coordinate(currentX, currentY));}}

currentBlock.remove(currentCell);

for (Coordinate coordinate : currentBlock) { if (liveCells.contains(coordinate)) { liveCellsCount++; }}

int aliveCells = liveCellsCount;

if (liveCells.contains(currentCell)) { if (aliveCells == 2 || aliveCells == 3) { nextGeneration.add(currentCell); }} else { if (aliveCells == 3) { nextGeneration.add(currentCell); }}}}

return nextGeneration;}

Page 43: Abilitare l'agilità con il design semplice

Cos'è la duplicazione?public Cell cellAt(int x, int y) { // [...]}

public Set<Cell> neighboursOf(int x, int y) { // [...]}

public bool isAliveAt(int x, int y) { // [...]}

Page 44: Abilitare l'agilità con il design semplice

Duplicazione di conoscenza, non di righe di codice

Page 45: Abilitare l'agilità con il design semplice

Riduco la duplicazione?public Cell cellAt(Coordinate coordinate) { // [...]}

public Set<Cell> neighboursOf(Coordinate coordinate) { // [...]}

public bool isAliveAt(Coordinate coordinate) { // [...]}

public class Coordinate { public int getX(); public int getY();}

Page 46: Abilitare l'agilità con il design semplice

Attrattore di comportamentipublic Cell cellAt(Coordinate coordinate) { // [...]}

public bool isAliveAt(Coordinate coordinate) { // [...]}

public class Coordinate { public Set<Coordinate> neighbours() { // [...] }}

Page 47: Abilitare l'agilità con il design semplice

Ridurre la duplicazione => Aumentare la coesione

Page 48: Abilitare l'agilità con il design semplice

É più importante ridurre la duplicazione o chiarire l'intento?

Page 49: Abilitare l'agilità con il design semplice

Le regole 2 e 3 lavorano in simbiosi

Page 50: Abilitare l'agilità con il design semplice

The Simple Design Dinamo (@jbrains)

Page 51: Abilitare l'agilità con il design semplice

1. passa tutti i test

2. esprime l'intento, non contiene duplicazione

3. viene realizzato con il minor numero di elementi possibili

Page 52: Abilitare l'agilità con il design semplice

Rimuoviamo il codice morto.

Page 53: Abilitare l'agilità con il design semplice

Facciamo emergere solo gli elementi necessari oggi

Page 54: Abilitare l'agilità con il design semplice

Il design è semplice se:1. posso verificarne il comportamento rapidamente

2. ha poco accoppiamento ed è molto coeso

3. è conciso

Page 55: Abilitare l'agilità con il design semplice

Costo del cambiamento (eXtreme Programming)

tempo

cost

o ca

mbi

amen

to

Page 56: Abilitare l'agilità con il design semplice

In conclusione

Page 57: Abilitare l'agilità con il design semplice

Per essere agili dobbiamo poter cambiare il nostro software con costi contenuti

Page 58: Abilitare l'agilità con il design semplice

Usiamo il design per ridurre e controllare il costo del cambiamento

Page 59: Abilitare l'agilità con il design semplice

Il design semplice ci indica la direzione

Page 60: Abilitare l'agilità con il design semplice

"Simplicity is prerequisite for reliability."Edsger W. Dijkstra

Page 61: Abilitare l'agilità con il design semplice

Per approfondire● K. Beck: eXtreme Programming Explained

● C. Haines: Understanding the Four Rules of Simple Designhttps://leanpub.com/4rulesofsimpledesign

● J.B.Rainsberger: Putting an age old battle to resthttp://blog.thecodewhisperer.com/permalink/putting-an-age-old-battle-to-rest

● M. Fowler: BeckDesignRuleshttps://martinfowler.com/bliki/BeckDesignRules.html

● C2 Wiki: Xp Simplicity Ruleshttp://wiki.c2.com/?XpSimplicityRules

Page 62: Abilitare l'agilità con il design semplice

Gabriele Tondi

@racingDeveloper [email protected]

Page 63: Abilitare l'agilità con il design semplice

Grazie!

Page 64: Abilitare l'agilità con il design semplice

Rimini, 25-27 Maggio 2017

http://www.socrates-conference.it

Page 65: Abilitare l'agilità con il design semplice

Domande?