Thursday, 15 January 2015

Proxy Design Pattern Implementation

Proxy Design Pattern

Hibernate                                                                                              Core Java


Question :- What is Proxy Design Pattern

As per GOF :-"Provide a surrogate or placeholder for another object to control access over it."

This design pattern helps us to create a wrapper over real object. It helps to control in accessing of the real object with the help of proxy object. 

  • This(Proxy design) pattern works on the principal of exposing Java object through a proxy instead of real object.

  • For securing an actual object this pattern can be used. Service provider does not want actual class to be visible to any client Instead It would be shared as per Client contract agreement . Service provider may agree to share only a part of Service with it's client and for that It may expose a different contract in the form of interface in java.

  • Client is not aware of actual object and through Proxy only relevant behavior of actual object will be exposed to client.

  • This pattern will help for lazily loading of an object. Data will be loaded only when it is actually required in an operation till then only proxy to real object will be kept as reference. So as to invoke desired method later and retrieve the actual instance.


The main intention of a proxy is to control access to the target object rather then to enhance the functionality of the target object.There are ways that proxies can provide access control which includes : -
  • Synchronization
  • Authentication
  • Remote Access
  • Lazy instantiation

Now considering a example where we can execute few command to open a specified application. Here the twist is opening any normal application is fine but opening a specific application should be controlled and we should provide access to those users who is having all type of permissions. Here a proxy class can be used to provide controlled access to those programs.

AppExecutor.java

package com.gaurav.designpattern.proxy;
/**
 * @author Gaurav
 * 
 */

public interface AppExecutor {
public boolean openApplication(String appName) throws Exception;
}


AppExecutorImpl.java

package com.gaurav.designpattern.proxy;
/**
 * @author Gaurav
 * 
 */

import java.io.IOException;

public class AppExecutorImpl implements AppExecutor{

@Override
public boolean openApplication(String appName) throws IOException {
boolean successFlag = false;
try{
Runtime.getRuntime().exec(appName);
successFlag = true;
}catch(IOException ioe){
System.out.println("Error message is : "+ioe.getMessage());
}
return successFlag;
}
}


AppExecutorProxy.java

package com.gaurav.designpattern.proxy;
/**
 * @author Gaurav
 * 
 */

public class AppExecutorProxy implements AppExecutor{
private boolean IsManagerLevelPermission = false;
    private AppExecutor appExecutor;
     
    public AppExecutorProxy(String userName, String password){
        if("Gaurav".equals(userName) && "Kumar#2013".equals(password)) 
        IsManagerLevelPermission = true;
        appExecutor = new AppExecutorImpl();
    }
     
    @Override
    public boolean openApplication(String appName) throws Exception {
        boolean success = false;
    if(IsManagerLevelPermission){
            appExecutor.openApplication(appName);
            success = true;
        }else{
            if(appName.trim().startsWith("mspaint")){
                throw new Exception("mspaint application is only available to managers.");
            }else{
                appExecutor.openApplication(appName);
                success = true;
            }
        }
    return success;
    }
}


ProxyDesignPatternDemo.java

package com.gaurav.designpattern.proxy;
/**
 * @author Gaurav
 * 
 */

public class ProxyDesignPatternDemo {
public static void main(String[] args){
        AppExecutor executor = new AppExecutorProxy("Gaurav", "welcome321");
        try {
           executor.openApplication("calc");
           executor.openApplication("notepad");
           boolean isExecuted = executor.openApplication("mspaint");
           System.out.println("Is mspaint app is executed : "+isExecuted);
        } catch (Exception e) {
            System.out.println("Error occurred is : "+e.getMessage());
        }
         
    }
}


Result:-

Error occurred is : mspaint application is only available to managers.

Note:- Here we are passing the wrong password which is not matching with the specified password.

Spring MVC                                           Spring Transaction                                        Web-Services

Monday, 3 November 2014

Flyweight Design Pattern Implementation

Flyweight Design Pattern

Flyweight design pattern falls under Structural design pattern. This will help to make instances of classes on the fly to improve performance efficiently. This helps to make the instance of the similar class sharing some common state to be reused as much as possible to boost the performance and minimize the memory consumption. The idea behind this pattern is to reduce the load of memory by sharing objects.

The best example is String API in java. In Java, String objects are managed as flyweight objects. Lets see the below example where we can find that what benefits are there to use this design pattern:-

package com.gaurav.designpattern.flyweight;

public class StringPoolTest {
public static void main(String args[]) {
String name = "Gaurav";
String nameVar = "Gaurav";
if (name == nameVar) {
System.out
.println("Both objects are referring to the same memory location in order to minimize memory");
}
}
}

Result:-

Both objects are referring to the same memory location in order to minimize memory


*****Now Consider on the example where we need to create different shapes like circle, rectangle and square in different colors at run-time. Instead of creating multiple instances of same shape type and color, if it has been already created reuse the same. We will see the example below.

Shape.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public interface Shape {
public String getColor();
public void draw();
}

Circle.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Circle implements Shape{

private String color;
public Circle(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Cirle having color : "+color);
}
}

Rectangle.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Rectangle implements Shape{

private String color;
public Rectangle(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Rectangle having color : "+color);
}

}

Square.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public class Square implements Shape{

private String color;
public Square(String color){
this.color = color;
}
@Override
public String getColor() {
return color;
}

@Override
public void draw() {
System.out.println("Drawing Square having color : "+color);
}
}

ShapeType.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
public enum ShapeType {
SQUARE,
RECTANGLE,
CIRCLE
}

ShapeFactory.java

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

public class ShapeFactory {

private static ShapeFactory instance;
private List<Shape> shapePool;

private ShapeFactory() {
shapePool = new ArrayList<Shape>(0);
}

public Shape getShape(ShapeType shapeType, String color) {
Shape shape = null;
switch (shapeType) {
case SQUARE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Square(color);
shapePool.add(shape);
}
break;

case RECTANGLE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Rectangle(color);
shapePool.add(shape);
}
break;
case CIRCLE:
shape = getShapeUsingPool(shapeType, color);
if (shape == null) {
shape = new Circle(color);
shapePool.add(shape);
}
break;
}
return shape;
}

private Shape getShapeUsingPool(ShapeType shapeType, String color) {
Shape shapeP = null;
for (Shape shape : shapePool) {

if (shapeType.equals(ShapeType.SQUARE)) {
if (shape instanceof Square && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

if (shapeType.equals(ShapeType.RECTANGLE)) {
if (shape instanceof Rectangle && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

if (shapeType.equals(ShapeType.CIRCLE)) {
if (shape instanceof Circle && color.equals(shape.getColor())) {
shapeP = shape;
break;
}
}

}

return shapeP;
}

public int getOverallObjectCreated() {
return shapePool.size();
}
public static ShapeFactory getInstance() {
if (instance == null) {
instance = new ShapeFactory();
}
return instance;
}
}

FlyweightdesignPatternDemo.java

package com.gaurav.designpattern.flyweight;
/**
 * @author Gaurav
 * 
 */
import java.util.Random;

public class FlyweightdesignPatternDemo {
public static void main(String args[]) {
ShapeFactory shapeFactory = ShapeFactory.getInstance();
ShapeType shapeTypes[] = { ShapeType.CIRCLE, ShapeType.RECTANGLE,
ShapeType.SQUARE };
String colors[] = { "RED", "MAGENTA", "PINK", "BLUE", "BLACK", "YELLOW" };

Random random = new Random();
for (int i = 0; i < 15; i++) {
ShapeType shapeType = shapeTypes[random.nextInt(shapeTypes.length)];
String color = colors[random.nextInt(colors.length)];
Shape shape = shapeFactory.getShape(shapeType, color);
shape.draw();
}
System.out
.println("Numbers of overall Objects created after object pool are : "
+ shapeFactory.getOverallObjectCreated());
}
}

Results:

Drawing Cirle having color : BLACK
Drawing Rectangle having color : BLUE
Drawing Cirle having color : BLUE
Drawing Rectangle having color : PINK
Drawing Rectangle having color : RED
Drawing Cirle having color : BLACK
Drawing Square having color : RED
Drawing Cirle having color : MAGENTA
Drawing Square having color : YELLOW
Drawing Rectangle having color : MAGENTA
Drawing Square having color : RED
Drawing Square having color : BLACK
Drawing Cirle having color : BLACK
Drawing Rectangle having color : RED
Drawing Rectangle having color : MAGENTA
Numbers of overall Objects created after object pool are : 10