Monday, May 13, 2013

Going technical...Builder pattern

"House" when I say this word I know many of you would imagine the place where you are currently living or the place where you lived when you were a kid. It is likely that two different individuals may have two different versions of the house that they are familiar with. But still the basic steps followed for the construction of those houses remain the same. Well now you must be thinking what those basic steps that I am talking about.

When a house is built regardless of the outside appearance of the house one must follow a fundamental sequence of actions to complete the house.

  • 1. Dig the land for foundation
  • 2. Lay the foundation
  • 3. Construct columns and beams
  • 4. Construct side walls or partition walls
  • 5. Fix the roof

In general any house that you can think of must have gone through the above stages of construction. Now that we are clear of the fact that we can generalize the process of constructing a house. We could identify this as a set of stages that must be followed to construct any house.

I guess now you are becoming clearer and clearer of what the title says. "Builder Pattern". So our builder will follow the above sequence and will successfully be able to build a house. If we introduce set of builders which follow the same steps of construction but add some additional touch to the final outcome we could have houses with different appearance.

How are we going to use this in software design. Yes , enough talking start coding then....
public class House {

 private String foundation;
 private String columns;
 private String beams;
 private String walls;
 private String roof;

 public String getFoundation() {
   return foundation;
 }
 public void setFoundation(String foundation) {
   this.foundation = foundation;
 }
 public String getColumns() {
   return columns;
 }
 public void setColumns(String columns) {
   this.columns = columns;
 }
 public String getBeams() {
   return beams;
 }
 public void setBeams(String beams) {
   this.beams = beams;
 }
 public String getWalls() {
   return walls;
 }
 public void setWalls(String walls) {
   this.walls = walls;
 }
 public String getRoof() {
   return roof;
 }
 public void setRoof(String roof) {
   this.roof = roof;
 }
}


public interface HouseBuilder {
 void digFoundation();
 void layFoundation();
 void constructColumnsBeams();
 void constructSideWallsPartitions();
 void fixRoof();
 House completeHouse();
}


public class CityHouseBuilder implements HouseBuilder {

 private House cityHouse = new House();

 public void digFoundation() {
   System.out.println("Dig foundation using an excavation machine");
 }

 public void layFoundation() {
   System.out.println("Lay foundation using Rubble , Cement and steel");
   cityHouse.setFoundation("Rubble , Cement , Steel");
 }

 public void constructColumnsBeams() {
   System.out.println("Construct columns and beams using steel and concrete");
   cityHouse.setColumns("Concrete , Steel");
   cityHouse.setBeams("Concrete . Steel");
 }

 public void constructSideWallsPartitions() {
   System.out.println("Construct side walls with bricks and cement");
   cityHouse.setWalls("Bricks , Cement");
 }

 public void fixRoof() {
   System.out.println("Fix roof with timber and roof tiles");
   cityHouse.setRoof("Timber , Roof Tiles");
 }

 public House completeHouse() {
   return this.cityHouse;
 }

}


public class VillageHouseBuilder implements HouseBuilder {

 private House villageHouse = new House();

 public void digFoundation() {
   System.out.println("Dig foundation using hand held tools");
 }

 public void layFoundation() {
   System.out.println("Lay a simple foundation using rubble and clay");
   villageHouse.setFoundation("Rubble and Clay");
 }

 public void constructColumnsBeams() {
   System.out.println("Fix wooded columns and wooden beams");
   villageHouse.setColumns("Wooden");
   villageHouse.setBeams("Wooden");
 }

 public void constructSideWallsPartitions() {
   System.out.println("Cover the side walls with hay and card board");
   villageHouse.setWalls("Hay and Cardboard");
 }

 public void fixRoof() {
   System.out.println("Fix the roof with hay");
   villageHouse.setRoof("Hay");
 }

 public House completeHouse() {
   return this.villageHouse;
 }

}


public class Main {

 public static void main(String[] args) {
   System.out.println("Village House :");
   //Build a Village House
   HouseBuilder builder = new VillageHouseBuilder();
   House house = buildHouse(builder);
   //
   System.out.println("City House :");
   //Build a City House
   builder = new CityHouseBuilder();
   house = buildHouse(builder);
 }

 public static House buildHouse(HouseBuilder builder){
   House house = null;
   builder.digFoundation();
   builder.layFoundation();
   builder.constructColumnsBeams();
   builder.constructSideWallsPartitions();
   builder.fixRoof();
   house = builder.completeHouse();
   return house;
 }

}

Sunday, March 10, 2013

Going Technical...Iterator design pattern

It has been quite sometime since I wrote the last post on this blog. In fact I tried few times to write something new but due to lack of time I was not able to do that. Also I was unable to find a simple yet elegant real life analogy to explain the "Iterator" design pattern.

Anyways now that I have found an analogy which may be good enough for this. Let's see whether you can grasp the idea without much effort.

We all are familiar with multistory buildings. Usually these buildings have some sort of fire alarming systems. When an accidental fire occurs these systems alert the occupants of the building so that they could move to a safe place. In addition to that when such fire alarming happens there may be an evacuation procedure to follow.Once the building occupants have moved to a safe ground someone would be in charge of making sure that all the occupants have arrived to the safe ground.Now that let's see how we could use this analogy to understand "Iterator" pattern.

"Iterator" design pattern is used when there is a need to inspect every single element in a group of elements and to do something with those. Usually this group of elements belongs to another parent data structure and when there is a need to inspect the elements in the group one has to request it from the parent data structure. The parent data structure is not supposed to reveal its internal information yet it has to allow inspection of all the elements

Well above paragraph tells us what Iterator design pattern is supposed to do. It is time to see how this fits to our analogy. Our analogy has a multistory building , occupants , fire alarming system and an evacuation procedure. The multistory building can be seen as the parent data structure. Occupants can be seen as the group of elements. Fire alarming system and evacuation procedure can be seen as the way how elements are exposed to outside for some sort of processing. When the evacuation procedure is followed occupants are supposed to take the stair case and walk to the safe ground one after the other.

Let's try putting these in code now,

package dranilev.blogspot.sg;

import java.util.ArrayList;
import java.util.List;

public class MultistoryBuilding implements FireAlarmAware{

  private List buildingOccupants = new ArrayList();

  public OccupantIterator evacuateOccupants() {
   OccupantIterator occupantIterator = new OccupantIterator();
   List iteratorOccupants = new ArrayList();
   iteratorOccupants.addAll(buildingOccupants);
   occupantIterator.setOccupants(iteratorOccupants);
   return occupantIterator;
  }

  public void occupyBuilding(Occupant occupant){
   this.buildingOccupants.add(occupant);
  }
}


package dranilev.blogspot.sg;

public interface FireAlarmAware {
  public OccupantIterator evacuateOccupants();
}


package dranilev.blogspot.sg;

import java.util.List;

public class OccupantIterator {
  private List occupants;

  public List getOccupants() {
   return occupants;
  }

  public void setOccupants(List occupants) {
   this.occupants = occupants;
  }

  public Occupant getNextOccupant(){
   Occupant nextOccupant = null;
   if(this.occupants != null && this.occupants.size() > 0){
    nextOccupant = this.occupants.get(0);
    this.occupants.remove(nextOccupant);
   }
   return nextOccupant;
  }

  public boolean hasNextOccupant(){
   boolean hasNext = false;
   if(this.occupants != null && this.occupants.size() > 0){
    hasNext = true;
   }
   return hasNext;
  }
}


package dranilev.blogspot.sg;

public class Occupant {
  private String name;
  private String age;
  private String sex;

  public String getName() {
   return name;
  }
  public void setName(String name) {
   this.name = name;
  }
  public String getAge() {
   return age;
  }
  public void setAge(String age) {
   this.age = age;
  }
  public String getSex() {
   return sex;
  }
  public void setSex(String sex) {
   this.sex = sex;
  }
  public void move(){
   System.out.println("moving " + name +" to a safe ground");
  }
}


package dranilev.blogspot.sg;

public class Main {

  public static void main(String[] args) {

   //construct a multi story building
   MultistoryBuilding multistoryBuilding = new MultistoryBuilding();
   //occupy the building
   for(int i = 0 ; i < 200 ; i++){
    Occupant occupant = new Occupant();
    occupant.setAge(i+"");
    occupant.setName("Occupant-"+i);
    if(i%2 ==0){
     occupant.setSex("Male");
    }else{
     occupant.setSex("Female");
    }
    multistoryBuilding.occupyBuilding(occupant);
  }

   //something happened , fire alarm activated evacuate occupants now
   OccupantIterator occupantIterator = multistoryBuilding.evacuateOccupants();
   while(occupantIterator.hasNextOccupant()){
    Occupant occupant = occupantIterator.getNextOccupant();
    occupant.move();
   }
  }

}