Saturday, December 26, 2015

Builder Design pattern


The builder pattern is another useful pattern that helps create complex objects. While using it is not a must, it allows developpers to reduce the complexity while instantiating an object with too many fields. It is also used to make object instantiation code more readable. In this tutorial, we will go through an example of how to implement this pattern in Java.

Suppose we have the following object:
 public class Profile {

     private String salutation;
     private String occupation;
     private String name;
     private String location;
     private String description;
     private String eMail;
     private String pictureUrl;
     private List hobbies;
     private String birthday;
   
     public Profile(String salutation, String name, String position, String location, String description, String eMail, String pictureUrl, List hobbies, String birthday){
         this.name = name;
         this.occupation = position;
         this.location = location;
         this.description = description;
         this.eMail = eMail;
         this.salutation = salutation;
         this.pictureUrl = pictureUrl;
         this.hobbies = hobbies;
         this.birthday = birthday;
     }
   
     public String getName() {
         return name;
     }

     public void setName(String name) {
         this.name = name;
     }

     public String getPosition() {
         return occupation;
     }

     public void setPosition(String position) {
         this.occupation = position;
     }

     public String getLocation() {
         return location;
     }

     public void setLocation(String location) {
         this.location = location;
     }

     public String getDescription() {
         return description;
     }
     public void setDescription(String description) {
         this.description = description;
     }

     public String geteMail() {
         return eMail;
     }

     public void seteMail(String eMail) {
         this.eMail = eMail;
     }

     public String getSalutation() {
         return salutation;
     }

     public void setSalutation(String salutation) {
         this.salutation = salutation;
     }
  public String getPictureUrl() {
   return pictureUrl;
  }
  public void setPictureUrl(String pictureUrl) {
   this.pictureUrl = pictureUrl;
  }
  public List getHobbies() {
   return hobbies;
  }
  public void setHobbies(List hobbies) {
   this.hobbies = hobbies;
  }
  public String getBirthday() {
   return birthday;
  }
  public void setBirthday(String birthday) {
   this.birthday = birthday;
  }
       
 
   
 }


If we want to instantiate a Profile object, one way to do it is: 

Profile profile = new Profile("Mr.", "Developper", "Dummy User", "France", "Cool Profile", "dummy@test.com", "server/profile.png", Arrays.asList("technology","soccer", "blogging") , "26/05/1990");

Notice the important number of parameters used by Profile constructor. While it is 100% ok to build objects this way, it can be confusing for developper figuring out which parameter is for which property. To simplify the creation of Profile, we can use a builder such as: 
public class ProfileBuilder {
   private String salutation;
     private String occupation;
     private String name;
     private String location;
     private String description;
     private String eMail;
     private String pictureUrl;
     private List<String> hobbies;
     private String birthday;
     
     public ProfileBuilder(){
      
      
     }
     
     
     public ProfileBuilder salutation(String salutation){
      this.salutation = salutation;
      
      return this;
     }
     
    public ProfileBuilder occupation(String occupation){
     this.occupation = occupation;
      return this;
     }
    
    public ProfileBuilder name(String name){
     this.name = name;
     return this;
    }
    
    public ProfileBuilder location(String location){
     this.location = location;
     return this;
    }
    
    public ProfileBuilder description(String description){
     this.description = description;
     return this;
    }
    
    public ProfileBuilder eMail(String eMail){
     this.eMail = eMail;
     return this;
    }
    
    public ProfileBuilder pictureUrl(String pictureUrl){
     this.pictureUrl = pictureUrl;
     return this;
    }
    
    public ProfileBuilder hobbies(List hobbies){
     this.hobbies = hobbies;
     return this;
    }
    
    public ProfileBuilder birthday(String birthday){
     this.birthday = birthday;
     return this;
    }
    
    
    public Profile build(){
     
     return new Profile(salutation, occupation, name, location, description, eMail, pictureUrl, hobbies, birthday);
    }

}

We need to adjust the profile constructor accordingly:
     public Profile(ProfileBuilder builder){
         this.name = builder.name;
         this.occupation = builder.occupation;
         this.location = builder.location;
         this.description = builder.description;
         this.eMail = builder.eMail;
         this.salutation = builder.salutation;
         this.pictureUrl = builder.pictureUrl;
         this.hobbies = builder.hobbies;
         this.birthday = builder.birthday;
     }

Now we can instantiate a Profile this way:
Profile profile = new ProfileBuilder()
                         .salutation("Mr.")
                         .occupation("Developper")
                         .name("Dummy User")
                         .location("France")
                         .description("Cool Profile")
                         .eMail("dummy@test.com")
                         .pictureUrl("server/profile.png")
                         .hobbies(Arrays.asList("technology","soccer", "blogging"))
                         .birthday("26/05/1990")
                          .build();
                         
  



Saturday, December 12, 2015

Observer (Pub/Sub) Design Pattern


The observer pattern is among the most used object oriented design patterns. It allows the designer to automate fields updates when there is a dependency between objects. Advocates of the observer pattern have identified many benefits from using it such as:
- promoting loose coupling
- efficiency
- flexibility: you can add an observer to a subject  any time

In this tutorial, we will go through an example of the Observer pattern in Java. As the name Publisher/Subscriber may suggest, there are two entites: a publisher and a subscriber, or an observer and a subject.

Example: Suppose we want to monitor changes in the car engine oil level. There are several units that wants to get updated about these changes: the Engine itsellf, the Dashboard, and the Cooling Unit. We want these parts to be automatically updated on any change without having to intervene manually.

First of all, let's get our interfaces up :

public interface Observer {
 public void update(int oilLevel);
}
public interface Subject {
 public void register(Observer o);
 public void unregister(Observer o);
 public void notifyObserver();
}


Then, as you may have dedcuted from the example, the engine oil level is the Subject. We will call it EngineOil.

public class EngineOil implements Subject {
 
 List<Observer> observers;
 
 int oilLevel;

 
 public EngineOil(){
 observers = new ArrayList();
 }
 public void register(Observer o) {
  // TODO Auto-generated method stub
  observers.add(o);
 }
 public void unregister(Observer o) {
  // TODO Auto-generated method stub
  int index = observers.indexOf(o);
  observers.remove(index);
 }
 public void notifyObserver() {
  for(Observer observer:observers){
   observer.update(oilLevel);
  }
 }
 public void setLiquidLevel(int oilLevel){
  this.oilLevel = oilLevel;
  notifyObserver();
 }
 
 public int getLiquidLevel(){
  return this.oilLevel;
 }
}


The Observers in our case are: CarDashboard, CarEngine, Cooling Unit.


public class CarDashboard implements Observer {


 int oilLevel;
 
 public CarDashboard(int oilLevel){
  this.oilLevel = oilLevel;
 }
 

 public void update(int oilLevel) {
  // TODO Auto-generated method stub
  this.oilLevel = oilLevel;
  System.out.println(this.getClass().getSimpleName() + ": oil level changed to " + oilLevel);
 }


public class CarEngine implements Observer {
 int oilLevel;
 public CarEngine(int oilLevel){
  this.oilLevel = oilLevel;
 }
 
 public void update(int oilLevel){
  this.oilLevel = oilLevel;
  System.out.println(this.getClass().getSimpleName() + ": oil level changed to " + oilLevel);
 }

}


public class CoolingUnit implements Observer {
        int oilLevel;

 public CoolingUnit(int oilLevel){
  this.oilLevel = oilLevel;
 }
 
 public void update(int oilLevel){
  this.oilLevel = oilLevel;
  System.out.println(this.getClass().getSimpleName() + ": oil level changed to " + oilLevel);
 }

}



We can now test our pattern:

public static void main(String[] args) {
  // TODO Auto-generated method stub
  
  EngineOil oil = new EngineOil();
  //No observer yet
  oil.setLiquidLevel(50);
  
  //Adding new observers
  CarEngine engine = new CarEngine(oil.getLiquidLevel());
  oil.register(engine);
  
  CoolingUnit unit = new CoolingUnit(oil.getLiquidLevel());
  oil.register(unit);
  
  CarDashboard board = new CarDashboard(oil.getLiquidLevel());
  oil.register(board);
  
  //changing the level
  
  oil.setLiquidLevel(45);
  oil.setLiquidLevel(25);
  oil.setLiquidLevel(20);

 }

Result: