SlideShare ist ein Scribd-Unternehmen logo
1 von 55
Downloaden Sie, um offline zu lesen
Codice Legacy,
usciamo dal pantano!
 Simone Casciaroli (@simonecasc)
       Stefano Leli (@sleli)
Bird Watching Game
  http://github.com/sleli/BirdWatching
Il Gioco
• Simulatore di Bird Watching
• Una sorta di “battaglia navale”...
 ma qui gli assi sono 3 (gli uccelli
 volano)
Classe GameField
       Responsabilità                     Collaborazioni

Gestisce la collezione di Birds
Dispone il campo da gioco
Valida il campo da gioco          Classe Bird
Inizializza il campo (start)
Gestisce le logiche degli shot
Refactoring Hints

Rimozione della duplicazione
Rimozione degli if
Oggetti invece che primitive type
Tell don’t ask
Passi di refactoring
Duplicazione
Duplicazione (semplice)

@Before
	 public void Setup() {
        field = new GameField(10,5,3, new FieldSize(10,5,3));
	 }
Duplicazione (semplice)
public GameField(int width, int height, int depth,
FieldSize fieldSize) {
	 	 this.width = width;
	 	 this.height = height;
	 	 this.depth = depth;
	 	 this.fieldSize = fieldSize;
	 	 birds = new ArrayList<Bird>();
	 }
Duplicazione (semplice)

//Place the birds on the fields
	 private void placeBirds(PlacingMode type) throws Exception {
      ...
	      Location location = new Location(new Random().nextInt(this.width),
                                        new Random().nextInt(this.height));
	 	    bird.setLocation(location);
	 	    if (!(bird instanceof Chicken))
	 	        bird.setHeight(new Random().nextInt(this.depth));
	 	 ...
	 }
Eliminiamola!
Eliminiamola!
@Before
	 public void Setup() {
        field = new GameField(new FieldSize(10,5,3));
	 }
Eliminiamola!
@Before
	 public void Setup() {
        field = new GameField(new FieldSize(10,5,3));
	 }


public GameField(FieldSize fieldSize) {
	 	 this.fieldSize = fieldSize;
	 	 birds = new ArrayList<Bird>();
	 }
Eliminiamola!
             @Before
             	 public void Setup() {
                     field = new GameField(new FieldSize(10,5,3));
             	 }


             public GameField(FieldSize fieldSize) {
             	 	 this.fieldSize = fieldSize;
             	 	 birds = new ArrayList<Bird>();
             	 }

//Place the birds on the fields
	   private void placeBirds(PlacingMode type) throws Exception {
...
	   	   	   	  Location location = new Location(new Random().nextInt(fieldSize.width()),
                 new Random().nextInt(fieldSize.height()));
	   	   	   	  bird.setLocation(location);
	   	   	   	  if (!(bird instanceof Chicken))
	   	   	   	  	   bird.setHeight(new Random().nextInt(fieldSize.depth()));
	   	   ...
	   }
Diamo a Cesare
ciò che è di Cesare
public class Location {
	 int x = 0;
	 int y = 0;
	
	 public Location (int x, int y) {
	 	 this.x = x;
	 	 this.y = y;
	 }

}
bird.setLocation(location);
if (!(bird instanceof Chicken))
	 bird.setHeight(new Random().nextInt(this.depth));
bird.setLocation(location);
if (!(bird instanceof Chicken))
	 bird.setHeight(new Random().nextInt(this.depth));

     Bird duck = new Duck();
     duck.setLocation(new Location(10,5));
     duck.setHeight(3);
bird.setLocation(location);
if (!(bird instanceof Chicken))
	 bird.setHeight(new Random().nextInt(this.depth));

     Bird duck = new Duck();
     duck.setLocation(new Location(10,5));
     duck.setHeight(3);

   int h = bird.getHeight();
   Location location = bird.getLocation();
   int x = location.x;
   int y = location.y;
   isValid = fieldSize.isWithinField(h, x, y);
Location location = new Location(new Random().nextInt(fieldSize.width()),
                                 new Random().nextInt(fieldSize.height()),
                                 new Random().nextInt(fieldSize.depth()));
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 int h = bird.getHeight();
	 	 Location location = bird.getLocation();
	 	 int x = location.x;
	 	 int y = location.y;
	 	 isValid = fieldSize.isWithinField(h, x, y);
	 	 if (!isValid)
	 	 	 break;
	 }
	 return isValid;
}
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 Location location = bird.getLocation();
	 	 int h = location.h;
	 	 int x = location.x;
	 	 int y = location.y;
	 	 isValid = fieldSize.isWithinField(h, x, y);
	 	 if (!isValid)
	 	 	 break;
	 }
	 return isValid;
}
public boolean shot(int x, int y, int h) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
	 	 	 int height = bird.getHeight();
	 	 	 Location location = bird.getLocation();
	 	 	 hit = location.x == x && location.y == y && height == h;
	 	 	 if (hit)
	 	 	 {
	 	 	 	 bird.sing();
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
public boolean shot(int x, int y, int h) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
	 	 	 Location location = bird.getLocation();
	 	 	 hit = location.x == x && location.y == y && location.h == h;
	 	 	 if (hit)
	 	 	 {
	 	 	 	 bird.sing();
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
public abstract class Bird {
	 Location location;
	 int height;
	
	 public void setHeight(int height) throws Exception{
	 	 this.height = height;	
	 }
	
	 public int getHeight() {
	 	 return height;
	 }
	
	 public void setLocation(Location location) {
	 	 this.location = location;
	 	
	 }
	
	 public Location getLocation() {
	 	 return location;
	 }
	
	 public abstract void sing();
}
Serve ancora?
private void placeBirds(PlacingMode type) throws Exception {
	 	 	
	 	 //Random Distribution
	 	 if (type == PlacingMode.Random) {
	 	 	 for(Bird bird : birds) {
	 	 	 	 Location location = new Location(new Random().nextInt(fieldSize.width()),
                                              new Random().nextInt(fieldSize.eighth()),
                                              new Random().nextInt(fieldSize.depth()));
	 	 	 	 bird.setLocation(location);
	 	 	 	 if (!(bird instanceof Chicken))
	 	 	 	 	 bird.setHeight(new Random().nextInt(this.depth));
	 	 	 }
	 	 }
	 	 //Custom Distribution
	 	 else if (type == PlacingMode.Custom) {
	 	 	
	 	 }
	 }
Tell, don’t Ask
public boolean shot(int x, int y, int h) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
	 	 	 Location location = bird.getLocation();
	 	 	 hit = location.x == x && location.y == y && location.h == h;
	 	 	 if (hit)
	 	 	 {
	 	 	 	 bird.sing();
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
Applied
public boolean shot(Location shotLocation) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
	 	 	 hit = shotLocation.equals(bird.getLocation());
	 	 	 if (hit)
	 	 	 {
	 	 	 	 bird.sing();
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
Let’s apply it another time
public boolean shot(Location shotLocation) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
        hit = bird.wasHit(shotLocation)
	 	 	 if (hit)
	 	 	 {
	 	 	 	 bird.sing();
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
Another time too
public boolean shot(Location shotLocation) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
        hit = bird.wasHit(shotLocation)
	 	 	 if (hit)
	 	 	 {
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
Programmiamo ad oggetti o
     a tipi primitivi...?
   private boolean isGameFieldValid()
   {
   	 boolean isValid = true;
   	 for(Bird bird : birds) {
   	 	 Location location = bird.getLocation();
   	 	 int h = location.h;
   	 	 int x = location.x;
   	 	 int y = location.y;
   	 	 isValid = fieldSize.isWithinField(h, x, y);
   	 	 if (!isValid)
   	 	 	 break;
   	 }
   	 return isValid;
   }
...ad Oggetti
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 isValid = fieldSize.isWithinField(bird.getLocation());
	 	 if (!isValid)         Text
	 	 	 break;
	 }
	 return isValid;
}
Gli IF proprio non ci
      piacciono!
Come procediamo?
private void placeBirds(PlacingMode type) throws Exception {
	 	 	
	 	 //Random Distribution
	 	 if (type == PlacingMode.Random) {
	 	 	 for(Bird bird : birds) {
	 	 	 	 Location location = new Location(new Random().nextInt(fieldSize.width()),
                                              new Random().nextInt(fieldSize.eighth()),
                                              new Random().nextInt(fieldSize.depth()));
	 	 	 	 bird.setLocation(location);
	 	 	 }
	 	 }
	 	 //Custom Distribution
	 	 else if (type == PlacingMode.Custom) {
	 	 	
	 	 }
	 }
I Passi di refactoring
•   Estratta responsabilità di “Random placing strategy” in
    una classe

•   estratta interfaccia IPlacingStrategy

•   creata class NullPlacingStrategy

•   creata Factory per Placing strategy

•   inline metodo placeBirds

•   trasformata la factory in un field ed estratto come
    parametro del costruttore
Il risultato
public class PlacingStrategyFactory {                                                        public interface IPlacingStrategy {

	   public IPlacingStrategy create(PlacingMode type,                                         	     void place(List<Bird> birds);
                                   FieldSize fieldSize) {
	   	   if (type == PlacingMode.Random) {                                                    }
	   	   	    return new RandomPlacingStrategy(fieldSize);
	   	   }
                                                                      public class NullPlacingStrategy implements IPlacingStrategy {
	   	   return new NullPlacingStrategy();
	   }                                                                 	     @Override
                                                                      	     public void place(List<Bird> birds) {
}                                                                     	     	    // Do nothing
                                                                      	     }

                                                                      }


                                        public class RandomPlacingStrategy implements IPlacingStrategy {
                                        	    private FieldSize fieldSize;

                                        	    public RandomPlacingStrategy(FieldSize fieldSize) {
                                        	    	    this.fieldSize = fieldSize;
                                        	    }

                                        	    @Override
                                        	    public void place(List<Bird> birds) {
                                        	    	    for(Bird bird : birds) {
                                        	    	    	     Location location = new Location(new Random().nextInt(fieldSize.width()),
                                        	    	    	     	    	     	    	     	     	    	       new Random().nextInt(fieldSize.height()),
                                        	    	    	     	    	     	    	     	     	    	       new Random().nextInt(fieldSize.depth()));
                                        	    	    	     bird.setLocation(location);
                                        	    	    }
                                        	    }

                                        }
Il risultato
public class GameField {
   ...
	 public boolean startGame(PlacingMode pm) {
	 	 placingStrategyFactory.create(pm, fieldSize).place(birds);
	 	 gameStarted = isGameStarted();
	 	 return gameStarted;
	 }
   ...
}
Altri IF che non ci
          piacciono
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 isValid = fieldSize.isWithinField(bird.getLocation());
	 	 if (!isValid)
	 	 	 break;
	 }
	 return isValid;
}
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 isValid = isValid && fieldSize.isWithinField(bird.getLocation());
	 }
	 return isValid;
}




                     what does it mean?

                                                           Groovy



                                                    Java + Guava
Stesso discorso
public boolean shot(Location shotLocation) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
        hit = bird.wasHit(shotLocation)
	 	 	 if (hit)
	 	 	 {
	 	 	 	 break;
	 	 	 }
	 	 }
	 }
    return hit;
}
public boolean shot(Location shotLocation) {
	 boolean hit = false;
	 if (gameStarted)
	 {
	 	 for(Bird bird : birds) {
        hit = hit || bird.wasHit(shotLocation)
	 	 }
	 }
    return hit;
}


                                or

                                                   Groovy



                                                 Java + Guava
Di nuovo sulle
responsabilità
Notate qualcosa?
private boolean isGameFieldValid()
{
	 boolean isValid = true;
	 for(Bird bird : birds) {
	 	 isValid = isValid && fieldSize.isWithinField(bird.getLocation());
	 }
	 return isValid;
}

  public boolean shot(Location shotLocation) {
  	 boolean hit = false;
  	 if (gameStarted)
  	 {
  	 	 for(Bird bird : birds) {
          hit = hit || bird.wasHit(shotLocation)
  	 	 }
  	 }
      return hit;
  }
BirdsArmy
ed ecco i chiamanti

private boolean isGameStarted() {
	 return birds.areAllBirdsPlacedWithinField(fieldSize);
}
	
public boolean shot(Location shotLocation) {
	 return birds.anyBirdWasHit(shotLocation) && gameStarted;
}
Doppia personalita’
Conclusioni
 Test funzionali attorno al codice da refattorizzare

         Refactoring ad ogni step e’ l’ideale

Se si parte con codice legacy usate le techniche viste
Conclusioni

Rimozione della duplicazione
Rimozione degli if
Oggetti invece che primitive type
Tell don’t ask
Repository


http://github.com/sleli/BirdWatching
GRAZIE

http://joind.in/4513


     @simonecasc
        @sleli

Weitere ähnliche Inhalte

Was ist angesagt?

Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on Python
Daker Fernandes
 
Camouflage: Automated Anonymization of Field Data (ICSE 2011)
Camouflage: Automated Anonymization of Field Data (ICSE 2011)Camouflage: Automated Anonymization of Field Data (ICSE 2011)
Camouflage: Automated Anonymization of Field Data (ICSE 2011)
James Clause
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 

Was ist angesagt? (20)

PythonOOP
PythonOOPPythonOOP
PythonOOP
 
ES6 and AngularAMD
ES6 and AngularAMDES6 and AngularAMD
ES6 and AngularAMD
 
Clips basics how to make expert system in clips | facts adding | rules makin...
Clips basics  how to make expert system in clips | facts adding | rules makin...Clips basics  how to make expert system in clips | facts adding | rules makin...
Clips basics how to make expert system in clips | facts adding | rules makin...
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 
SWP - A Generic Language Parser
SWP - A Generic Language ParserSWP - A Generic Language Parser
SWP - A Generic Language Parser
 
Arrows in perl
Arrows in perlArrows in perl
Arrows in perl
 
λ | Lenses
λ | Lensesλ | Lenses
λ | Lenses
 
Functional programming with php7
Functional programming with php7Functional programming with php7
Functional programming with php7
 
Good Code
Good CodeGood Code
Good Code
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogramming
 
Functional Pattern Matching on Python
Functional Pattern Matching on PythonFunctional Pattern Matching on Python
Functional Pattern Matching on Python
 
밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AI밑바닥부터 시작하는 의료 AI
밑바닥부터 시작하는 의료 AI
 
Camouflage: Automated Anonymization of Field Data (ICSE 2011)
Camouflage: Automated Anonymization of Field Data (ICSE 2011)Camouflage: Automated Anonymization of Field Data (ICSE 2011)
Camouflage: Automated Anonymization of Field Data (ICSE 2011)
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuan
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
 
Exploit Development: EzServer Buffer Overflow oleh Tom Gregory
Exploit Development: EzServer Buffer Overflow oleh Tom GregoryExploit Development: EzServer Buffer Overflow oleh Tom Gregory
Exploit Development: EzServer Buffer Overflow oleh Tom Gregory
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicit
 
08 functions
08 functions08 functions
08 functions
 
Elixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicitElixir & Phoenix – fast, concurrent and explicit
Elixir & Phoenix – fast, concurrent and explicit
 

Ähnlich wie Codice legacy, usciamo dal pantano! @iad11

create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdfcreate a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
duttakajal70
 
package com.test;public class Team {    private String teamId;.pdf
package com.test;public class Team {    private String teamId;.pdfpackage com.test;public class Team {    private String teamId;.pdf
package com.test;public class Team {    private String teamId;.pdf
aparnacollection
 
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docxsrcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
whitneyleman54422
 
question.(player, entity ,field and base.java codes are given)Stop.pdf
question.(player, entity ,field and base.java codes are given)Stop.pdfquestion.(player, entity ,field and base.java codes are given)Stop.pdf
question.(player, entity ,field and base.java codes are given)Stop.pdf
shahidqamar17
 
Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good code
Giordano Scalzo
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
arjuncorner565
 
Given a scenario where an farmer agent walks around a meadow.pdf
Given a scenario where an farmer agent walks around a meadow.pdfGiven a scenario where an farmer agent walks around a meadow.pdf
Given a scenario where an farmer agent walks around a meadow.pdf
sales79
 
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdfWrite a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
rozakashif85
 
Easily mockingdependenciesinc++ 2
Easily mockingdependenciesinc++ 2Easily mockingdependenciesinc++ 2
Easily mockingdependenciesinc++ 2
drewz lin
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC
 
public class AVLTreeT extends ComparableT extends BSTT { p.pdf
public class AVLTreeT extends ComparableT extends BSTT {   p.pdfpublic class AVLTreeT extends ComparableT extends BSTT {   p.pdf
public class AVLTreeT extends ComparableT extends BSTT { p.pdf
agmobiles
 

Ähnlich wie Codice legacy, usciamo dal pantano! @iad11 (20)

create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdfcreate a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
create a Tic Tac Toe game using JSP Scripting elements and a JSP pag.pdf
 
package com.test;public class Team {    private String teamId;.pdf
package com.test;public class Team {    private String teamId;.pdfpackage com.test;public class Team {    private String teamId;.pdf
package com.test;public class Team {    private String teamId;.pdf
 
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docxsrcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
srcArtifact.javasrcArtifact.javaclassArtifactextendsCave{pub.docx
 
question.(player, entity ,field and base.java codes are given)Stop.pdf
question.(player, entity ,field and base.java codes are given)Stop.pdfquestion.(player, entity ,field and base.java codes are given)Stop.pdf
question.(player, entity ,field and base.java codes are given)Stop.pdf
 
Why Sifu?
Why Sifu?Why Sifu?
Why Sifu?
 
Why Sifu
Why SifuWhy Sifu
Why Sifu
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Better Software: introduction to good code
Better Software: introduction to good codeBetter Software: introduction to good code
Better Software: introduction to good code
 
Introduzione a C#
Introduzione a C#Introduzione a C#
Introduzione a C#
 
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdfModify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
Modify HuffmanTree.java and HuffmanNode.java to allow the user to se.pdf
 
Given a scenario where an farmer agent walks around a meadow.pdf
Given a scenario where an farmer agent walks around a meadow.pdfGiven a scenario where an farmer agent walks around a meadow.pdf
Given a scenario where an farmer agent walks around a meadow.pdf
 
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdfWrite a class (BasketballTeam) encapsulating the concept of a tea.pdf
Write a class (BasketballTeam) encapsulating the concept of a tea.pdf
 
Easily mockingdependenciesinc++ 2
Easily mockingdependenciesinc++ 2Easily mockingdependenciesinc++ 2
Easily mockingdependenciesinc++ 2
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
はじめてのGroovy
はじめてのGroovyはじめてのGroovy
はじめてのGroovy
 
Scala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 WorldScala vs Java 8 in a Java 8 World
Scala vs Java 8 in a Java 8 World
 
public class AVLTreeT extends ComparableT extends BSTT { p.pdf
public class AVLTreeT extends ComparableT extends BSTT {   p.pdfpublic class AVLTreeT extends ComparableT extends BSTT {   p.pdf
public class AVLTreeT extends ComparableT extends BSTT { p.pdf
 
ES6(ES2015) is beautiful
ES6(ES2015) is beautifulES6(ES2015) is beautiful
ES6(ES2015) is beautiful
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
3 1-1
3 1-13 1-1
3 1-1
 

Mehr von Stefano Leli

Agile retrospective,an example
Agile retrospective,an exampleAgile retrospective,an example
Agile retrospective,an example
Stefano Leli
 
Codice legacy, usciamo dal pantano!
Codice legacy, usciamo dal pantano!Codice legacy, usciamo dal pantano!
Codice legacy, usciamo dal pantano!
Stefano Leli
 
Design Pattern In Pratica
Design Pattern In PraticaDesign Pattern In Pratica
Design Pattern In Pratica
Stefano Leli
 
Workshop Su Refactoring
Workshop Su RefactoringWorkshop Su Refactoring
Workshop Su Refactoring
Stefano Leli
 
Intoduzione Alle Metodologie Agili
Intoduzione Alle Metodologie AgiliIntoduzione Alle Metodologie Agili
Intoduzione Alle Metodologie Agili
Stefano Leli
 

Mehr von Stefano Leli (17)

Agile quackery a brief history of the worst ways to cure everything
Agile quackery   a brief history of the worst ways to cure everythingAgile quackery   a brief history of the worst ways to cure everything
Agile quackery a brief history of the worst ways to cure everything
 
Agile goes Hollywood - Un approccio empirico alle trasformazioni agili
Agile goes Hollywood - Un approccio empirico alle trasformazioni agiliAgile goes Hollywood - Un approccio empirico alle trasformazioni agili
Agile goes Hollywood - Un approccio empirico alle trasformazioni agili
 
Succeding with feature teams
Succeding with feature teamsSucceding with feature teams
Succeding with feature teams
 
User Story Mapping
User Story MappingUser Story Mapping
User Story Mapping
 
La tua prima kanban board
La tua prima kanban boardLa tua prima kanban board
La tua prima kanban board
 
Dinosaur Carpaccio - How to implement valuable micro-requirements
Dinosaur Carpaccio - How to implement valuable micro-requirementsDinosaur Carpaccio - How to implement valuable micro-requirements
Dinosaur Carpaccio - How to implement valuable micro-requirements
 
From Vision To Product
From Vision To ProductFrom Vision To Product
From Vision To Product
 
Agile retrospective,an example
Agile retrospective,an exampleAgile retrospective,an example
Agile retrospective,an example
 
User stories writing - Codemotion 2013
User stories writing   - Codemotion 2013User stories writing   - Codemotion 2013
User stories writing - Codemotion 2013
 
User Stories Writing
User Stories WritingUser Stories Writing
User Stories Writing
 
XP Game
XP GameXP Game
XP Game
 
Il project manager e lo sviluppo agile. Separati in casa?
Il project manager e lo sviluppo agile. Separati in casa?Il project manager e lo sviluppo agile. Separati in casa?
Il project manager e lo sviluppo agile. Separati in casa?
 
Codice legacy, usciamo dal pantano!
Codice legacy, usciamo dal pantano!Codice legacy, usciamo dal pantano!
Codice legacy, usciamo dal pantano!
 
Manage software dependencies with ioc and aop
Manage software dependencies with ioc and aopManage software dependencies with ioc and aop
Manage software dependencies with ioc and aop
 
Design Pattern In Pratica
Design Pattern In PraticaDesign Pattern In Pratica
Design Pattern In Pratica
 
Workshop Su Refactoring
Workshop Su RefactoringWorkshop Su Refactoring
Workshop Su Refactoring
 
Intoduzione Alle Metodologie Agili
Intoduzione Alle Metodologie AgiliIntoduzione Alle Metodologie Agili
Intoduzione Alle Metodologie Agili
 

Kürzlich hochgeladen

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Kürzlich hochgeladen (20)

Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

Codice legacy, usciamo dal pantano! @iad11

  • 1. Codice Legacy, usciamo dal pantano! Simone Casciaroli (@simonecasc) Stefano Leli (@sleli)
  • 2. Bird Watching Game http://github.com/sleli/BirdWatching
  • 3. Il Gioco • Simulatore di Bird Watching • Una sorta di “battaglia navale”... ma qui gli assi sono 3 (gli uccelli volano)
  • 4.
  • 5. Classe GameField Responsabilità Collaborazioni Gestisce la collezione di Birds Dispone il campo da gioco Valida il campo da gioco Classe Bird Inizializza il campo (start) Gestisce le logiche degli shot
  • 6. Refactoring Hints Rimozione della duplicazione Rimozione degli if Oggetti invece che primitive type Tell don’t ask
  • 9. Duplicazione (semplice) @Before public void Setup() { field = new GameField(10,5,3, new FieldSize(10,5,3)); }
  • 10. Duplicazione (semplice) public GameField(int width, int height, int depth, FieldSize fieldSize) { this.width = width; this.height = height; this.depth = depth; this.fieldSize = fieldSize; birds = new ArrayList<Bird>(); }
  • 11. Duplicazione (semplice) //Place the birds on the fields private void placeBirds(PlacingMode type) throws Exception { ... Location location = new Location(new Random().nextInt(this.width), new Random().nextInt(this.height)); bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(this.depth)); ... }
  • 13. Eliminiamola! @Before public void Setup() { field = new GameField(new FieldSize(10,5,3)); }
  • 14. Eliminiamola! @Before public void Setup() { field = new GameField(new FieldSize(10,5,3)); } public GameField(FieldSize fieldSize) { this.fieldSize = fieldSize; birds = new ArrayList<Bird>(); }
  • 15. Eliminiamola! @Before public void Setup() { field = new GameField(new FieldSize(10,5,3)); } public GameField(FieldSize fieldSize) { this.fieldSize = fieldSize; birds = new ArrayList<Bird>(); } //Place the birds on the fields private void placeBirds(PlacingMode type) throws Exception { ... Location location = new Location(new Random().nextInt(fieldSize.width()), new Random().nextInt(fieldSize.height())); bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(fieldSize.depth())); ... }
  • 16. Diamo a Cesare ciò che è di Cesare
  • 17. public class Location { int x = 0; int y = 0; public Location (int x, int y) { this.x = x; this.y = y; } }
  • 18.
  • 19. bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(this.depth));
  • 20. bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(this.depth)); Bird duck = new Duck(); duck.setLocation(new Location(10,5)); duck.setHeight(3);
  • 21. bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(this.depth)); Bird duck = new Duck(); duck.setLocation(new Location(10,5)); duck.setHeight(3); int h = bird.getHeight(); Location location = bird.getLocation(); int x = location.x; int y = location.y; isValid = fieldSize.isWithinField(h, x, y);
  • 22.
  • 23. Location location = new Location(new Random().nextInt(fieldSize.width()), new Random().nextInt(fieldSize.height()), new Random().nextInt(fieldSize.depth()));
  • 24. private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { int h = bird.getHeight(); Location location = bird.getLocation(); int x = location.x; int y = location.y; isValid = fieldSize.isWithinField(h, x, y); if (!isValid) break; } return isValid; }
  • 25. private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { Location location = bird.getLocation(); int h = location.h; int x = location.x; int y = location.y; isValid = fieldSize.isWithinField(h, x, y); if (!isValid) break; } return isValid; }
  • 26. public boolean shot(int x, int y, int h) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { int height = bird.getHeight(); Location location = bird.getLocation(); hit = location.x == x && location.y == y && height == h; if (hit) { bird.sing(); break; } } } return hit; }
  • 27. public boolean shot(int x, int y, int h) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { Location location = bird.getLocation(); hit = location.x == x && location.y == y && location.h == h; if (hit) { bird.sing(); break; } } } return hit; }
  • 28. public abstract class Bird { Location location; int height; public void setHeight(int height) throws Exception{ this.height = height; } public int getHeight() { return height; } public void setLocation(Location location) { this.location = location; } public Location getLocation() { return location; } public abstract void sing(); }
  • 29. Serve ancora? private void placeBirds(PlacingMode type) throws Exception { //Random Distribution if (type == PlacingMode.Random) { for(Bird bird : birds) { Location location = new Location(new Random().nextInt(fieldSize.width()), new Random().nextInt(fieldSize.eighth()), new Random().nextInt(fieldSize.depth())); bird.setLocation(location); if (!(bird instanceof Chicken)) bird.setHeight(new Random().nextInt(this.depth)); } } //Custom Distribution else if (type == PlacingMode.Custom) { } }
  • 30. Tell, don’t Ask public boolean shot(int x, int y, int h) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { Location location = bird.getLocation(); hit = location.x == x && location.y == y && location.h == h; if (hit) { bird.sing(); break; } } } return hit; }
  • 31. Applied public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = shotLocation.equals(bird.getLocation()); if (hit) { bird.sing(); break; } } } return hit; }
  • 32. Let’s apply it another time public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = bird.wasHit(shotLocation) if (hit) { bird.sing(); break; } } } return hit; }
  • 33. Another time too public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = bird.wasHit(shotLocation) if (hit) { break; } } } return hit; }
  • 34. Programmiamo ad oggetti o a tipi primitivi...? private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { Location location = bird.getLocation(); int h = location.h; int x = location.x; int y = location.y; isValid = fieldSize.isWithinField(h, x, y); if (!isValid) break; } return isValid; }
  • 35. ...ad Oggetti private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { isValid = fieldSize.isWithinField(bird.getLocation()); if (!isValid) Text break; } return isValid; }
  • 36. Gli IF proprio non ci piacciono!
  • 37. Come procediamo? private void placeBirds(PlacingMode type) throws Exception { //Random Distribution if (type == PlacingMode.Random) { for(Bird bird : birds) { Location location = new Location(new Random().nextInt(fieldSize.width()), new Random().nextInt(fieldSize.eighth()), new Random().nextInt(fieldSize.depth())); bird.setLocation(location); } } //Custom Distribution else if (type == PlacingMode.Custom) { } }
  • 38. I Passi di refactoring • Estratta responsabilità di “Random placing strategy” in una classe • estratta interfaccia IPlacingStrategy • creata class NullPlacingStrategy • creata Factory per Placing strategy • inline metodo placeBirds • trasformata la factory in un field ed estratto come parametro del costruttore
  • 39. Il risultato public class PlacingStrategyFactory { public interface IPlacingStrategy { public IPlacingStrategy create(PlacingMode type, void place(List<Bird> birds); FieldSize fieldSize) { if (type == PlacingMode.Random) { } return new RandomPlacingStrategy(fieldSize); } public class NullPlacingStrategy implements IPlacingStrategy { return new NullPlacingStrategy(); } @Override public void place(List<Bird> birds) { } // Do nothing } } public class RandomPlacingStrategy implements IPlacingStrategy { private FieldSize fieldSize; public RandomPlacingStrategy(FieldSize fieldSize) { this.fieldSize = fieldSize; } @Override public void place(List<Bird> birds) { for(Bird bird : birds) { Location location = new Location(new Random().nextInt(fieldSize.width()), new Random().nextInt(fieldSize.height()), new Random().nextInt(fieldSize.depth())); bird.setLocation(location); } } }
  • 40. Il risultato public class GameField { ... public boolean startGame(PlacingMode pm) { placingStrategyFactory.create(pm, fieldSize).place(birds); gameStarted = isGameStarted(); return gameStarted; } ... }
  • 41. Altri IF che non ci piacciono private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { isValid = fieldSize.isWithinField(bird.getLocation()); if (!isValid) break; } return isValid; }
  • 42. private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { isValid = isValid && fieldSize.isWithinField(bird.getLocation()); } return isValid; } what does it mean? Groovy Java + Guava
  • 43. Stesso discorso public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = bird.wasHit(shotLocation) if (hit) { break; } } } return hit; }
  • 44. public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = hit || bird.wasHit(shotLocation) } } return hit; } or Groovy Java + Guava
  • 46. Notate qualcosa? private boolean isGameFieldValid() { boolean isValid = true; for(Bird bird : birds) { isValid = isValid && fieldSize.isWithinField(bird.getLocation()); } return isValid; } public boolean shot(Location shotLocation) { boolean hit = false; if (gameStarted) { for(Bird bird : birds) { hit = hit || bird.wasHit(shotLocation) } } return hit; }
  • 48. ed ecco i chiamanti private boolean isGameStarted() { return birds.areAllBirdsPlacedWithinField(fieldSize); } public boolean shot(Location shotLocation) { return birds.anyBirdWasHit(shotLocation) && gameStarted; }
  • 50.
  • 51.
  • 52. Conclusioni Test funzionali attorno al codice da refattorizzare Refactoring ad ogni step e’ l’ideale Se si parte con codice legacy usate le techniche viste
  • 53. Conclusioni Rimozione della duplicazione Rimozione degli if Oggetti invece che primitive type Tell don’t ask
  • 55. GRAZIE http://joind.in/4513 @simonecasc @sleli