Wednesday 14 August 2013

Design Pattern Overview

Design patterns represent the best practices used by experienced object-oriented software developers.

Design patterns are solutions to general problems that software developers faced during software development. These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time.

Gang of Four (GOF) In 1994, four authors Erich Gamma, Richard Helm; Ralph Johnson und John Vlissides published a book titled Design Patterns - Elements of Reusable Object-Oriented Software which initiated the concept of Design Pattern in Software development. These authors are collectively known as Gang of Four (GOF).
According to these authors design patterns are primarily based on the following principles of object orientated design. Program to an interface not an implementation
 Favor object composition over inheritance

Usage of Design Pattern 

Design Patterns have two main usages in software development.

Common platform for developers 

Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern.

Best Practices 

Design patterns have been evolved over a long period of time and they provide best solutions to certain problems faced during software development. Learning these patterns helps un-experienced developers to learn software design in an easy and faster way.

Types of Design Pattern
As per the design pattern reference book Design Patterns - Elements of Reusable Object-Oriented Software, there are 23 design patterns.

S.N.       Pattern & Description
1. Creational Patterns
These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case.
2. Structural Patterns
These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities.
3. Behavioral Patterns
These design patterns are specifically concerned with communication between objects.
4. J2EE Patterns
These design patterns are specifically concerned with the presentation tier. These patterns are identified by Sun Java Center.

Difference between forward and sendRedirect

forward

Control can be forward to resources available within the server from where the call is made. This transfer of control is done by the container internally and browser / client is not involved. This is the major difference between forward and sendRedirect. When the forward is done, the original request and response objects are transfered along with additional parameters if needed.

redirect

Control can be redirect to resources to different servers or domains. This transfer of control task is delegated to the browser by the container. That is, the redirect sends a header back to the browser / client. This header contains the resource url to be redirected by the browser. Then the browser initiates a new request to the given url. Since it is a new request, the old request and response object is lost.
For example, sendRedirect can transfer control from http://javapapers.com to http://anydomain.com but forward cannot do this.
‘session’ is not lost in both forward and redirect.
To feel the difference between forward and sendRedirect visually see the address bar of your browser,
in forward, you will not see the forwarded address (since the browser is not involved)
in redirect, you can see the redirected address.

When can we use forward and when can we use sendRedirect?

Technical scenario: redirect should be used
  1. If you need to transfer control to different domain
  2. To achieve separation of task.
For example, database update and data display can be separated by redirect. Do the PaymentProcess and then redirect to displayPaymentInfo. If the client refreshes the browser only the displayPaymentInfo will be done again and PyamenProcess will not be repeated. But if you use forward in this scenario, both PaymentProcess and displayPaymentInfo will be re-executed sequentially, which may result in incosistent data.
For other than the above two scenarios, forward is efficient to use since it is faster than sendRedirect.

Example for forward and sendRedirect based on real world

Consider the real world scenario, the milk man comes and asks for monthly payment to you in your house. Here house is the container and you are a resource existing in the container. Milk man is the client or browser.
He asks for the monthly payment to you, this is the request made by the browser to resource A. If you go inside your house and ask your mother (another resource B inside the same container) for the cash and come back and deliver to milkman this is called forward.
If you ask the milkman to speak himself to your mother inside your house or you ask the milkman to speak to your father who is in his office (different domain) then this is called redirect.

Adapter Design Pattern

Adapter pattern works as a bridge between two incompatible interfaces.
This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces.
This pattern involves a single class which is responsible to join functionality of independent or incompatible interfaces.
A real life example could be a case of card reader which acts as an adapter between memory card and a laptop. You plugins the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.
We are demonstrating use of Adapter pattern via following example in which an audio player device can play mp3 files only and wants to use an advanced audio player capable of playing vlc and mp4 files.
Implementation 
We've an interface MediaPlayer interface and a concrete class AudioPlayer implementing theMediaPlayer interface. AudioPlayer can play mp3 format audio files by default.

We're having another interface AdvancedMediaPlayer and concrete classes implementing theAdvancedMediaPlayer interface.These classes can play vlc and mp4 format files. We want to make AudioPlayer to play other formats as well.
To attain this, we've created an adapter class MediaAdapter which implements the MediaPlayer interface and uses AdvancedMediaPlayerobjects to play the required format. AudioPlayer uses the adapter class MediaAdapter passing it the desired audio type without knowing the actual class which can play the desired format. AdapterPatternDemo, our demo class will useAudioPlayer class to play various formats.

Class Diagram



Steps 
Use the following steps to implement the above mentioned design pattern.

Step 1 
Create interfaces for Media Player and Advanced Media Player.
MediaPlayer.java
public interface MediaPlayer {
           public void play(String audioType, String fileName);
}
AdvancedMediaPlayer.java
public interface AdvancedMediaPlayer {
           public void playVlc(String fileName);
           public void playMp4(String fileName);
}

Step 2
Create concrete classes implementing the AdvancedMediaPlayer interface.
VlcPlayer.java
public class VlcPlayer implements AdvancedMediaPlayer{ 
           @Override 
           public void playVlc(String fileName) { 
                      System.out.println("Playing vlc file. Name: "+ fileName); 
           } 
           @Override 
           public void playMp4(String fileName) { 
                      //do nothing 
           } 

Mp4Player.java 
public class Mp4Player implements AdvancedMediaPlayer{ 
           @Override 
           public void playVlc(String fileName) { 
                      //do nothing 
           } 
           @Override 
           public void playMp4(String fileName) { 
                      System.out.println("Playing mp4 file. Name: "+ fileName); 
           } 
}

Step 3 
Create adapter class implementing the MediaPlayer interface.
MediaAdapter.java 
public class MediaAdapter implements MediaPlayer { 
           AdvancedMediaPlayer advancedMusicPlayer; 
           public MediaAdapter(String audioType){ 
                      if(audioType.equalsIgnoreCase("vlc") ){ 
                                 advancedMusicPlayer = new VlcPlayer(); 
                      } else if (audioType.equalsIgnoreCase("mp4")){ 
                                 advancedMusicPlayer = new Mp4Player(); 
                     
          
           @Override 
           public void play(String audioType, String fileName) { 
                      if(audioType.equalsIgnoreCase("vlc")){ 
                                 advancedMusicPlayer.playVlc(fileName); 
                      }else if(audioType.equalsIgnoreCase("mp4")){
                                  advancedMusicPlayer.playMp4(fileName); 
                     
          
}
 

Step 4 
Create concrete class implementing the MediaPlayer interface. 
AudioPlayer.java 
public class AudioPlayer implements MediaPlayer { 
           MediaAdapter mediaAdapter; 
           @Override 
           public void play(String audioType, String fileName) { 
                      //inbuilt support to play mp3 music files 
                     if(audioType.equalsIgnoreCase("mp3")){ 
                                System.out.println("Playing mp3 file. Name: "+ fileName); 
                     
                      //mediaAdapter is providing support to play other file formats else
                     if(audioType.equalsIgnoreCase("vlc") || audioType.equalsIgnoreCase("mp4")){ 
                                mediaAdapter = new MediaAdapter(audioType); 
                                 mediaAdapter.play(audioType, fileName); 
                     } else{ 
                                System.out.println("Invalid media. "+ audioType + " format not supported"); 
                     
           }
}

Step 5 
Use the AudioPlayer to play different types of audio formats.
AdapterPatternDemo.java  
public class AdapterPatternDemo { 
           public static void main(String[] args) { 
                      AudioPlayer audioPlayer = new AudioPlayer(); 
                      audioPlayer.play("mp3", "beyond the horizon.mp3"); 
                      audioPlayer.play("mp4", "alone.mp4"); 
                      audioPlayer.play("vlc", "far far away.vlc"); 
                      audioPlayer.play("avi", "mind me.avi"); 
          
}

Step 6 
Verify the output. 
Playing mp3 file. Name: beyond the horizon.mp3 
Playing mp4 file. Name: alone.mp4 
Playing vlc file. Name: far far away.vlc 
Invalid media. avi format not supported