Monday 13 April 2015

Memento Design Pattern Implementation

Memento Design Pattern


Question:- What is Memento Design Pattern?

Answer:-This design pattern also falls under Behavioral design pattern. This(Mediator) pattern is used When we want to persist an object state so that in future we can restore to its previous state easily.
The participants which involves in this design pattern are :
  • Memento: This is the basic object that is stored in different states.
  • Originator: This sets and gets the values from the currently targeted Memento and also Creates new Mementos and assigns current values to them.
  • Caretaker: This helps to hold a List of all previous versions of the Mementos. It can store and retrieve stored Mementos. It acts like a repository and does not make changes to mementos


As per GOF :- “Captures and externalizes an object's internal state so that it can be restored later, all without violating encapsulation.”

Question:- When to use Memento design pattern?
Answer:- If we want to restore an object into a state that existed previously include: saving and restoring. For example the state of a player in a computer game or the implementation of an undo operation in a database like in any text editor.

Advantage of Memento Pattern:
  • It helps to keep the saved state external from key object which helps to maintain cohesion.
  • It keeps the key object's data encapsulated.
  • This design pattern provides easy-to-implement recovery capability.

Memento design pattern in Real world :- We have seen option in cellphone i.e. Restore phone data with factory settings

Other example :- Undo or backspace or ctrl+z is one of the most used operation in an editor. Memento design pattern is used to implement the undo operation.

b) Memento design pattern in Java :-
java.util.Date (the setter methods do that, Date is internally represented by a long value)
All implementations of java.io.Serializable
All implementations of javax.faces.component.StateHolder

We will see the implementation of this design pattern in the below example.
package com.gaurav.designpattern.memento;

Memento.java
/**
 * @author Gaurav
 *
 */
public class Memento {
private String objectState;

public Memento(String stateToSave) {
objectState = stateToSave;
}

public String retrieveSavedState() {
return objectState;
}
}

Originator.java

package com.gaurav.designpattern.memento;

/**
 * @author Gaurav
 *
 */
public class Originator {
private String objectState;

public void set(String state) {
System.out.println("Inside Originator, setting state to :- " + state);
this.objectState = state;
}

public Memento saveToMemento() {
System.out.println("Inside Originator saving the object state to Memento.");
return new Memento(objectState);
}

public void restoreFromMemento(Memento memento) {
objectState = memento.retrieveSavedState();
System.out.println("Inside Originator, object state after restoring from Memento :- "
+ objectState);
}
}


Caretaker.java


package com.gaurav.designpattern.memento;

/**
 * @author Gaurav
 *
 */
import java.util.ArrayList;
import java.util.List;

public class Caretaker {
private List<Memento> objSavedStates = new ArrayList<Memento>();

public void saveToMemento(Memento memento) {
objSavedStates.add(memento);
}

public Memento getFromMemento(int index) {
return objSavedStates.get(index);
}
}

MementoDesignPatternDemo.java

package com.gaurav.designpattern.memento;

/**
 * @author Gaurav
 *
 */
public class MementoDesignPatternDemo{
public static void main(String[] args) {
Originator originator = new Originator();
originator.set("Data State 1");
originator.set("Data State 2");
Caretaker caretaker = new Caretaker();
caretaker.saveToMemento(originator.saveToMemento());
originator.set("Data State 3");
caretaker.saveToMemento(originator.saveToMemento());
originator.set("Data State 4");
originator.restoreFromMemento(caretaker.getFromMemento(1));
}
}

Result:-

Inside Originator, setting state to :- Data State 1
Inside Originator, setting state to :- Data State 2
Inside Originator saving the object state to Memento.
Inside Originator, setting state to :- Data State 3
Inside Originator saving the object state to Memento.
Inside Originator, setting state to :- Data State 4
Inside Originator, object state after restoring from Memento :- Data State 3


Tuesday 17 March 2015

Mediator Design Pattern Implementation

Mediator Design Pattern


Question:- What is Mediator Design Pattern?
This design pattern falls under Behavioral design pattern. This(Mediator) pattern is used to reduce communication complexity between multiple objects or classes. It helps to centralize communication between objects into a mediator object. With the help of this pattern communication happens with the help of mediator so we achieves loose coupling.

As per GOF:-“Allows loose coupling by encapsulating the way disparate sets of objects interact and communicate with each other. Allows for the actions of each object set to vary independently of one another.”

Question:- When to use Mediator design pattern?
Answer:-If we need to centralize complex communications and control between related objects then this design pattern can be used.
Advantages:-
  • It helps to centralize control to manipulate participating objects and it also helps to simplfies maintenance of the system by centralizing control logic.
  • It helps to increases the reusability of the objects supported by the Mediator by decoupling them from the system.

In Mediator Design pattern, the classes that communicate with the mediator are known as Colleagues. The mediator implementation is known as the Concrete Mediator. Colleagues know about their mediator, and the mediator also knows about its colleagues.

Mediator example in JDK API
  • java.lang.reflect.Method#invoke()
  • java.util.Timer (all scheduleXXX() methods)
  • java.util.concurrent.Executor#execute()
  • java.util.concurrent.ExecutorService (the invokeXXX() and submit() methods)
  • java.util.concurrent.ScheduledExecutorService (all scheduleXXX() methods)


Live examples of Mediator design pattern

Mediator example in Real world :- Air traffic controller (ATC) is a mediator between multiple flights. It helps in communication between flights and co-oridates/controls landing & take-off. Two flights need not interact directly and there should not be any dependency between them. This dependency is solved by the mediator ATC.

We will see a sample program to implement mediator design pattern.

Messenger Interface as Mediator

package com.gaurav.designpattern.mediator;

/**
 * @author Gaurav
 *
 */
public interface Messenger {
    void addContact(Contact contact);
    
    public void sendMessage(Contact contact, String msg);
}

Contact class as Colleague component

package com.gaurav.designpattern.mediator;

/**
 * @author Gaurav
 *
 */
public abstract class Contact {
protected Messenger chatMediator;
    protected String name;
     
    public Contact(String name, Messenger messenger){
        this.chatMediator = messenger;
        this.name=name;
    }
     
    public abstract void send(String msg);
     
    public abstract void receive(String msg);
}


MessengerImpl class as Concrete Mediator

package com.gaurav.designpattern.mediator;

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

/**
 * @author Gaurav
 *
 */

public class MessengerImpl implements Messenger{
private List<Contact> contacts;
    
    public MessengerImpl(){
        this.contacts=new ArrayList<>();
    }
     
    @Override
    public void addContact(Contact contact){
        this.contacts.add(contact);
    }
     
    @Override
    public void sendMessage(Contact contact, String msg) {
        for(Contact userContact : this.contacts){
            if(userContact != contact){
                userContact.receive(msg);
            }
        }
    }
}


ContactImpl class as Concrete Colleague


package com.gaurav.designpattern.mediator;

/**
 * @author Gaurav
 *
 */
public class ContactImpl extends Contact{
public ContactImpl(String name, Messenger messenger) {
super(name, messenger);
}

@Override
public void send(String message) {
System.out.println("Sender "+this.name+" has sent message which is : = "+message);
chatMediator.sendMessage(this, message);
}

@Override
public void receive(String message) {
System.out.println("Receiver "+this.name+" has received message which is : = "+message);
}
}

MediatorDesignPatternDemo class as Caller


package com.gaurav.designpattern.mediator;

/**
 * @author Gaurav
 * 
 */
public class MediatorDesignPatternDemo {
public static void main(String args[]) {
Messenger messenger = new MessengerImpl();
Contact contact1 = new ContactImpl("Gaurav", messenger);
Contact contact2 = new ContactImpl("Sunita", messenger);
Contact contact3 = new ContactImpl("Aaditya", messenger);
Contact contact4 = new ContactImpl("Shivam", messenger);

messenger.addContact(contact1);
messenger.addContact(contact2);
messenger.addContact(contact3);
messenger.addContact(contact4);

contact1.send("Welcome to everyone in chat messenger");
}
}


Result:-

Sender Gaurav has sent message which is : = Welcome to everyone in chat messenger
Receiver Sunita has received message which is : = Welcome to everyone in chat messenger
Receiver Aaditya has received message which is : = Welcome to everyone in chat messenger
Receiver Shivam has received message which is : = Welcome to everyone in chat messenger


Wednesday 4 March 2015

Iterator Design Implementation

Iterator Design Pattern


Question:- What is Iterator Design Pattern?

This design pattern falls under Behavioral design pattern. This pattern is used to provide a command and standard way to tranverse through a collection of objects.

As per GOF :-“Provides a way to access the elements of an aggregate object without exposing its underlying represenation.”

An aggregate object is an object that contains other objects for the purpose of grouping those objects as an unit.
Participants of Iterator interface
  • Iterator – defines an interface for accessing and traversing elements.
  • Aggregate – Like a factory method, it defines an interface for creating an iterator object.
  • Concrete Aggregate – This implements the iterator interface and keeps track of the current position in the traversal.
Question:- When to use Iterator design pattern?
This pattern provides a mechanism that allows all elements of a collection to be accessed sequentially, with some operation being performed on each element. With the help of this mechanism we can iterate or looping over an encapsulated group of objects.
  • If we want to access a group of objects without exposing its internal representation.
  • If there are many traversals of objects need to be supported in the collection. It supports multiple, concurrent traversals.

Examples in JDK API
  • implementations of java.util.Iterator and its subclasses.
  • implementations of java.util.Enumeration

Live examples of Iterator design pattern

Iterating over a number of DTH channels or traversing through a song playlist using MP3 player are the live examples of this design pattern.

In the below example, we will see the implementation of Iterator design pattern

DTHChannelMenuEnum.java

package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
public enum DTHChannelMenuEnum {
HINDI, ENGLISH, TELEGU, ALL
}

DTHChannels.java

package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
public class DTHChannels {
private DTHChannelMenuEnum dthChannelMenuEnum;
private double channelFrequency;

public DTHChannels(DTHChannelMenuEnum channelEnum, double chFreq) {
this.dthChannelMenuEnum = channelEnum;
this.channelFrequency = chFreq;
}

public DTHChannelMenuEnum getDthChannelMenuEnum() {
return dthChannelMenuEnum;
}

public double getChannelFrequency() {
return channelFrequency;
}

@Override
public String toString() {
return "DTHChannelMenuEnum=" + this.dthChannelMenuEnum
+ " , ChannelFrequency=" + this.channelFrequency;
}
}


Channels.java


package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
public interface Channels {
 
public void addChannelInFavouriteMenu(DTHChannels dthChannels);
     
   public void removeChannelFromFavouriteMenu(DTHChannels dthChannels);
    
   public DTHMenuChannelIterator iterator(DTHChannelMenuEnum dthChannelMenuEnum);
}



DTHMenuChannelIterator.java


package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
public interface DTHMenuChannelIterator {
 
   public boolean hasNext();
     
   public DTHChannels next();
}



ChannelsImpl.java


package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
import java.util.ArrayList;
import java.util.List;

public class ChannelsImpl implements Channels{
private List<DTHChannels> dthChannelList = new ArrayList<DTHChannels>();

@Override
public void addChannelInFavouriteMenu(DTHChannels dthChannels) {
this.dthChannelList.add(dthChannels);
System.out.println(dthChannels.getDthChannelMenuEnum()+" channel with frequency "+dthChannels.getChannelFrequency()+" is added in the Favourite Menu.");
}

@Override
public void removeChannelFromFavouriteMenu(DTHChannels dthChannels) {
this.dthChannelList.remove(dthChannels);
System.out.println(dthChannels.getDthChannelMenuEnum()+" channel with frequency "+dthChannels.getChannelFrequency()+" is removed from the Favourite Menu.");
}

@Override
public DTHMenuChannelIterator iterator(DTHChannelMenuEnum dthChannelMenuEnum) {
System.out.println("\nTraversing for all DTH channels : ");
return new DTHMenuChannelIteratorImpl(dthChannelMenuEnum, this.dthChannelList);
}
private class DTHMenuChannelIteratorImpl implements DTHMenuChannelIterator
{

private DTHChannelMenuEnum dthChannelMenuEnum;
        private List<DTHChannels> channels;
        private int currentPosition;
        public DTHMenuChannelIteratorImpl(DTHChannelMenuEnum channelEnum,
                List<DTHChannels> dthChannelsArrList) {
            this.dthChannelMenuEnum = channelEnum;
            this.channels = dthChannelsArrList;
        }
        @Override
        public boolean hasNext() {
            while (currentPosition < channels.size()) {
            DTHChannels c = channels.get(currentPosition);
                if (c.getDthChannelMenuEnum().equals(dthChannelMenuEnum) || dthChannelMenuEnum.equals(DTHChannelMenuEnum.ALL)) {
                    return true;
                } else
                    currentPosition++;
            }
            return false;
        }
        @Override
        public DTHChannels next() {
        DTHChannels c = channels.get(currentPosition);
            currentPosition++;
            return c;
        }
    }
}



IteratorDesignPatternDemo.java



package com.gaurav.designpattern.iterator;
/**
 * @author Gaurav
 * 
 */
public class IteratorDesignPatternDemo {
private static Channels retrieveChannels() {
Channels channels = new ChannelsImpl();
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.HINDI, 98.7));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.ENGLISH, 99.8));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.TELEGU, 100.2));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.HINDI, 95.3));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.TELEGU, 98.9));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.ENGLISH, 95.3));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.HINDI, 105.6));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.HINDI, 111.4));
channels.addChannelInFavouriteMenu(new DTHChannels(
DTHChannelMenuEnum.HINDI, 112.9));
return channels;
}
public static void main(String[] args) {
Channels channels = retrieveChannels();
DTHMenuChannelIterator allChannelIterator = channels
.iterator(DTHChannelMenuEnum.ALL);
System.out.println("\nALL available Channels are : \n");
while (allChannelIterator.hasNext()) {
DTHChannels dthChannel = allChannelIterator.next();
System.out.println(dthChannel.toString());
}
System.out.println("\n---------------------------------------------------------------");
DTHMenuChannelIterator hindiChannelIterator = channels
.iterator(DTHChannelMenuEnum.HINDI);
System.out.println("\nHindi available Channels are : \n");
while (hindiChannelIterator.hasNext()) {
DTHChannels dthChannel = hindiChannelIterator.next();
System.out.println(dthChannel.toString());
}
}

}


Result : -

HINDI channel with frequency 98.7 is added in the Favourite Menu.
ENGLISH channel with frequency 99.8 is added in the Favourite Menu.
TELEGU channel with frequency 100.2 is added in the Favourite Menu.
HINDI channel with frequency 95.3 is added in the Favourite Menu.
TELEGU channel with frequency 98.9 is added in the Favourite Menu.
ENGLISH channel with frequency 95.3 is added in the Favourite Menu.
HINDI channel with frequency 105.6 is added in the Favourite Menu.
HINDI channel with frequency 111.4 is added in the Favourite Menu.
HINDI channel with frequency 112.9 is added in the Favourite Menu.

Traversing for all DTH channels : 

ALL available Channels are : 

DTHChannelMenuEnum=HINDI , ChannelFrequency=98.7
DTHChannelMenuEnum=ENGLISH , ChannelFrequency=99.8
DTHChannelMenuEnum=TELEGU , ChannelFrequency=100.2
DTHChannelMenuEnum=HINDI , ChannelFrequency=95.3
DTHChannelMenuEnum=TELEGU , ChannelFrequency=98.9
DTHChannelMenuEnum=ENGLISH , ChannelFrequency=95.3
DTHChannelMenuEnum=HINDI , ChannelFrequency=105.6
DTHChannelMenuEnum=HINDI , ChannelFrequency=111.4
DTHChannelMenuEnum=HINDI , ChannelFrequency=112.9

---------------------------------------------------------------

Traversing for all DTH channels : 

Hindi available Channels are : 

DTHChannelMenuEnum=HINDI , ChannelFrequency=98.7
DTHChannelMenuEnum=HINDI , ChannelFrequency=95.3
DTHChannelMenuEnum=HINDI , ChannelFrequency=105.6
DTHChannelMenuEnum=HINDI , ChannelFrequency=111.4
DTHChannelMenuEnum=HINDI , ChannelFrequency=112.9

Wednesday 18 February 2015

Interpreter design Implementation

 Interpreter Design Pattern

Hibernate                                                                                              Core Java



Question:- What is Interpreter Design Pattern?
This design pattern falls under Behavioral design pattern. This pattern provides a way to evaluate language expression. This design pattern involves in implementing an expression interface which tells to interpret a particular context.

As per GOF :-“Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.”

Question:- When to use Interpreter design pattern?
This design pattern is used for specialized computer languages which are often used to describe communication protocols.This design pattern is also used in symbol processing engine, SQL parsing etc.
  • Examples in JDK API
java.util.Patternand subclasses of java.text.Formatare few implementation examples of interpreter pattern used in JDK.
  • Live examples of Interpreter design pattern
  1. Google Translator is an example of interpreter pattern where the input can be in any language and we can get the output interpreted in another language.
  2. In java itself, this design pattern is implemented where java compiler interprets the java source code into byte code that is understandable by JVM.

Drawback

During implementation of Interpreter design pattern, it requires large piece of code for error checking and expression evaluation. So when the grammer is complicated then the required piece of code is complicated and hence it is very difficult to maintain and provide efficient code.

In the below example,we will see a sample of using interpreter design pattern.

InterpreterImplemeter.java

package com.gaurav.designpattern.interpreter;

/**
 * @author Gaurav
 * 
 */
public class InterpreterImplemeter {

public String getBinaryConversion(int number) {
return Integer.toBinaryString(number);
}

public String getHexadecimalConversion(int number) {
return Integer.toHexString(number);
}
}

ExpressionConversion.java

package com.gaurav.designpattern.interpreter;

/**
 * @author Gaurav
 * 
 */
public interface ExpressionConversion {
public String interpretData(InterpreterImplemeter interpreter);
}

IntegerToBinary.java


package com.gaurav.designpattern.interpreter;

/**
 * @author Gaurav
 *
 */
public class IntegerToBinary implements ExpressionConversion{
private int number;
public IntegerToBinary(int num){
this.number = num;
}
@Override
public String interpretData(InterpreterImplemeter interpreter) {
return interpreter.getBinaryConversion(this.number);
}
}


IntegerToHexadecimal.java


package com.gaurav.designpattern.interpreter;

/**
 * @author Gaurav
 *
 */
public class IntegerToHexadecimal implements ExpressionConversion{
private int number;
public IntegerToHexadecimal(int num){
this.number = num;
}
@Override
public String interpretData(InterpreterImplemeter interpreter) {
return interpreter.getHexadecimalConversion(this.number);
}
}


InterpreterDesignPatternDemo.java


package com.gaurav.designpattern.interpreter;

import java.util.Scanner;

/**
 * @author Gaurav
 * 
 */
public class InterpreterDesignPatternDemo {
public InterpreterImplemeter interPreter;

public InterpreterDesignPatternDemo(InterpreterImplemeter i) {
this.interPreter = i;
}

public String binaryConverter(int num) {
ExpressionConversion expressionConverter = new IntegerToHexadecimal(num);
return expressionConverter.interpretData(interPreter);
}

public String hexadecimalConverter(int num) {
ExpressionConversion expressionConverter = new IntegerToBinary(num);
return expressionConverter.interpretData(interPreter);
}
public static void main(String args[]) {
InterpreterDesignPatternDemo client = new InterpreterDesignPatternDemo(
new InterpreterImplemeter());

Scanner scanner = new Scanner(System.in);
System.out.println("Enter the conversion type either binary or hexa : ");
String conversionType = scanner.nextLine();
System.out.println("Enter the number for conversion : ");
int number = scanner.nextInt();
if("binary".equalsIgnoreCase(conversionType))
System.out.println(number + " in binary is : " + client.binaryConverter(number));
else if("hexa".equalsIgnoreCase(conversionType))
System.out.println(number + " in hexadecimal is : " + client.hexadecimalConverter(number));
else{
System.out.println("Unable to convert, please provide correct conversion type as mentioned.");
}
}
}


Result : - 

1st Execution : 

Enter the conversion type either binary or hexa : 
binary
Enter the number for conversion : 
10
10 in binary is : a

2nd Execution : 

Enter the conversion type either binary or hexa : 
hexa
Enter the number for conversion : 
10
10 in hexadecimal is : 1010

3rd Execution : 

Enter the conversion type either binary or hexa : 
octa
Enter the number for conversion : 
10
Unable to convert, please provide correct conversion type as mentioned.