Showing posts with label Patterns. Show all posts
Showing posts with label Patterns. Show all posts

Iterator Design Pattern in Java

Iterator Design Pattern in Java

Iterator pattern is a behavioral object design pattern. Iterator pattern allows for the traversal through the elements in a grouping of objects via a standardized interface defines the actions or methods that can be performed. These actions or methods able to traverse the objects, remove or add Object according to project needs. So keeping in mind about the pattern just we need to apply on top of our business logic's. 

If we look at Java widely used Iterator interface which used to iterate through elements in various Java collections. We can write our own iterator by implementing java.util.Iterator. This interface features the hasNext(), next(), and remove() methods. Lets take simple example of book stall which contains list of books with these few following information's like,

Book Name
Author
Price

Based on above example lets create Book class which holds the book details


public class Book {

 private String name;
 private String author;
 private int price;
 
 public Book(String name, String author, int price) {
  this.name = name;
  this.author = author;
  this.price = price;
 }
 public String getName() {
  return name;
 }
 public String getAuthor() {
  return author;
 }
 public int getPrice() {
  return price;
 }

 @Override
 public String toString() {
  return "----------\n\nBook Name : "+name+" \nAuthor    : "+author+"\nPrice     : Rs."+price; 
 } 
}




Next lets create Store class which contains list of various books and list actions like add books, removing, listing etc., can be performed. 


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

public class Store {
 
 List<Book> bookList = new ArrayList<Book>();
 
 public void addBook(Book item) {
  bookList.add(item);
 }

 public Iterator<Book> iterator() {
  return new BooksIterator();
 }

 class BooksIterator implements Iterator<Book> {
  int bookId = 0;

  @Override
  public boolean hasNext() {
   if (bookId >= bookList.size()) {
    return false;
   } else {
    return true;
   }
  }

  @Override
  public Book next() {
   return bookList.get(bookId++);
  }

  @Override
  public void remove() {
   bookList.remove(--bookId);
  }
 } 
}


Next lets implement the main class which feeds list of books into Store and iterates. For sample lets add 4 books and will test.


import java.util.Iterator;

public class BookStore {
 
 public static void main(String[] args) {
  Book b1 = new Book("Lightning", "Dean Koontz", 500);
  Book b2 = new Book("Roma: The Novel of Ancient Rome", "Steven Saylor", 452);
  Book b3 = new Book("Humility", "Andrew Murray", 334);
  Book b4 = new Book("Meditations", "Marcus Aurelius, Martin Hammond", 635);
  
  Store store = new Store();
  store.addBook(b1);
  store.addBook(b2);
  store.addBook(b3);
  store.addBook(b4);
  
  System.out.println("Display list of books in store");
  Iterator<Book> iterator = store.iterator();
  while (iterator.hasNext()) {
   Book item = iterator.next();
   System.out.println(item.toString());
   
   //Removing "Humility" from the book store list
   if(item.getName().equals("Humility")){
    iterator.remove();
   }
  }
  
  System.out.println("\n\n\nDisplay list of books in store after removing 'Humility' book");
  iterator = store.iterator();
  while (iterator.hasNext()) {
   Book item = iterator.next();
   System.out.println(item.toString());
  }
 }
}


OUTPUT:


Display list of books in store
----------

Book Name : Lightning 
Author    : Dean Koontz
Price     : Rs.500
----------

Book Name : Roma: The Novel of Ancient Rome 
Author    : Steven Saylor
Price     : Rs.452
----------

Book Name : Humility 
Author    : Andrew Murray
Price     : Rs.334
----------

Book Name : Meditations 
Author    : Marcus Aurelius, Martin Hammond
Price     : Rs.635



Display list of books in store after removing 'Humility' book
----------

Book Name : Lightning 
Author    : Dean Koontz
Price     : Rs.500
----------

Book Name : Roma: The Novel of Ancient Rome 
Author    : Steven Saylor
Price     : Rs.452
----------

Book Name : Meditations 
Author    : Marcus Aurelius, Martin Hammond
Price     : Rs.635

How to create fully Singleton design pattern class in Java

Today we will discuss about how to create fully Singleton class in Java. Before jumping to creation of Singleton class, lets list down some of the key features and usage of creating Singleton class in Java. 

What is Singleton design pattern class?

         In simple words Singleton class is nothing but having a single object or Instance of a class for entire lifetime of the application. 

       Singleton pattern is a common pattern we use in our day today code and projects in various places like reading a property file values, DB Connections etc.Restricting multiple Object or Instance creation on Class. Main property of singleton class is restricting the class Instance creation from outside Singleton class. This can be achieved by keeping private constructors. 

       Even by keeping private constructors other programmers can break singleton pattern and they can create instance outside class by other Java features like clone() and serialization. To avoid these loop hols we need to @Override clone() and readResolve() methods in our Singleton class.

       We can achieve this in 2 ways like Lazy initialization and Eager initialization in the class. Below are the small example which will explain about the Fully Singleton implementation by using Lazy initialization.


import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.Random;

import javax.management.InstanceAlreadyExistsException;

class MySingleton implements Serializable  {
    
 private static MySingleton obj = null;
    private int val;
    
    private MySingleton() throws InstanceAlreadyExistsException{
     if(obj != null){
      System.out.println("\nObject already created....");
      throw new InstanceAlreadyExistsException();
     }
 
     System.out.println("Inside Constructor..");
        val = new Random().nextInt();
    }

    public static MySingleton getInstance() throws InstanceAlreadyExistsException{
        if(obj == null){
            synchronized (MySingleton.class) {
                if(obj == null){
                    obj = new MySingleton();
                }
            }
        }
        return obj;
    }
    public int getVal(){
        return val;
    }
    public void setVal(int val){
     this.val = val;
    }
    
    @Override
    protected MySingleton clone() throws CloneNotSupportedException {
     // If user tries to clone the object then we are sending same class object
        try {
   return MySingleton.getInstance();
  } catch (InstanceAlreadyExistsException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return null; 
    }
    
    private Object readResolve() throws ObjectStreamException, InstanceAlreadyExistsException {
     // We are blocking deserilizing object and sending same class object
      return MySingleton.getInstance();
  }
}


Above MySingleton class contains private constructor, getter, setter, @Override clone method, readResolve method and static method to get the class instance. Apart from that we have class member variables like MySingleton (obj) and val. In constructor just we have assigned some random value to val just for identifying multiple instance has created are we are using same instance throughout the application and next we are throwing exception called InstanceAlreadyExistsException if already class instance created. Here we are blocking other user to create instance using java.lang.reflect.Constructor class to satisfy fully singleton pattern.

          In static method we are using double to identify class has already initialized or not. If already initialized then method we will return Object (obj) else condition will go inside synchronized block. Here we are using synchronized block to avoid multiple object creation under multi-threading.


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;

public class SingletonPattern {

    public static void main(String[] args)  {
     try{
         MySingleton obj1 = MySingleton.getInstance();
         MySingleton obj2 = obj1.clone();
        
         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\singleton.ser")); 
         oos.writeObject(obj1); 
         oos.close(); 
         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\singleton.ser")); 
         MySingleton obj3 = (MySingleton) ois.readObject(); 
         ois.close(); 
        
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal()+"\n\n");
         
         // Changing value in Object 3
         obj3.setVal(100);
         
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal()+"\n\n");
         
         // Changing value in Object 3
         obj2.setVal(1234);
         
         System.out.println("First Object      :: "+obj1.getVal());
         System.out.println("Clone Object      :: "+obj2.getVal());
         System.out.println("Serialized Object :: "+obj3.getVal());
         
         Constructor constructor = MySingleton.class.getDeclaredConstructor();
         constructor.setAccessible(true);
         MySingleton newInstance = (MySingleton) constructor.newInstance();
         
         System.out.println("NEW INSTANCE : "+newInstance.getVal());

     }catch (Exception e) {
   System.out.println(e.getCause());
  }
    }
}


In above class we created the Object (obj1) by calling static getInstance() method. 
         
         Next we have cloned the same Object (obj1) to other Object (obj2), since we have @Overrided clone() method in our first class it will return same Instance which have initialized at first time and we are blocking the cloning the Object here.

         Next we have serialized the Object (Obj1) into a file and then again we have deserialized the Object to (ob3). 

         Next we are changing the "val" value of Object (obj3) where we can see value changed in all 3 Objects in the Output and we can confirm that user can't create new Object through serializing. 

         Next we are changing the "val" value of Object (obj2) where same way value has changed in all 3 Objects in the Output and we can confirm that even by cloning user will same Object instead of new Object.

         Last we have testing whether are able to create instance using java.lang.reflect.Constructor class. In that case we will get exception called InstanceAlreadyExistsException and new instance can't be created. 

OUTPUT: 


Inside Constructor..
First Object      :: 739385266
Clone Object      :: 739385266
Serialized Object :: 739385266


First Object      :: 100
Clone Object      :: 100
Serialized Object :: 100


First Object      :: 1234
Clone Object      :: 1234
Serialized Object :: 1234

Object already created....
javax.management.InstanceAlreadyExistsException



Hope you are clear now how to create fully Singleton class. Please drop your comments below.