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();
   }
  }

}