Showing posts with label structural pattern. Show all posts
Showing posts with label structural pattern. Show all posts

Monday, December 11, 2017

Proxy Pattern

Definition -

    It provides a proxy implementation for another object and controls access to the real object.
   
Scenario -

    let us consider an example of Manufacturing of a car in a plant which produces a hatchback and a sedan.
based on the above scenario -
1) We will have an interface called car.

package ProxyPattern;

public interface car {
    
    public void manufacture();

}

2) We will have concrete classes called hatchback and sedan
hatchback.java
 
public class hatchback implements car {

    @Override
    public void manufacture() {
        
        System.out.println("Manufacturing a hatchback");
        
    }

}

sedan.java

package ProxyPattern;

public class sedan implements car {

    @Override
    public void manufacture() {
        
        System.out.println("Manufacturing a sedan");
        
    }

}

3) We will have an handler called carhandler which will be responsible for invoking the classes based on request.
package ProxyPattern;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class carhandler implements InvocationHandler {
    
    public Object realcar=null;
    
    public carhandler(Object realcar) {
        this.realcar=realcar;
    }
    

    @Override
    public Object invoke(Object duplicate, Method arg1, Object[] arg2) throws Throwable {
        
        Object temp=arg1.invoke(realcar, arg2);
        return temp;
    }

}


4) To see the pattern in action use the code below - 
package ProxyPattern;

import java.lang.reflect.Proxy;

public class proxydemo {

    public static void main(String[] args) {
        
        
        car ht=new hatchback();
        carhandler ch=new carhandler(ht);
        car duplicate = (car) Proxy.newProxyInstance(ht.getClass().getClassLoader(),ht.getClass().getInterfaces(),ch);
        
        duplicate.manufacture();

    }

}


Place to use -
1) When the object created is external to the system.
2) Requires access to the original object and in some cases allowing to have modified functionalities.



The code used above can be found in the link here

Facade Pattern


Definition -

    This provides a standard interface for all the interfaces in the system or sub system.   

Scenario -

    Let us take an example of building a house, the components walls, roof needs to come together in order to complete it. If you would approach to start this without the pattern then you would have to handle too many scenarios to ensure the classes are called in particular order. The facade pattern is used to make the job easier.
   
Based on the above scenario -
1) A class called walls which will build all the walls.

package FacadePattern;

public class walls {
    
    public void buildwalls() {
        System.out.println("Building walls");
    }


}

2) A class called roof which will build the roof.
package FacadePattern;

public class roofs {
    
    public void buildroofs() {
        System.out.println("Building roofs");
    }

}

3) A class called housefacade which will take care of the calling a class by the interface instead of calling roof and walls separately.
 
package FacadePattern;

public class housefacade {
    
    private walls wall=new walls();
    private roofs roof=new roofs();
    
    public void build() {
        wall.buildwalls();
        roof.buildroofs();
    }

}

4) To see the pattern in action use the code below 
package FacadePattern;

public class facadedemo {
    
    public static void main(String args[]) {
        
        housefacade house=new housefacade();
        house.build();
        
    }
    
}


Place to use -
1) Use this when you have too many interfaces and you want to simplify the interaction with the client.
2) People generally use this while building web services since a single web services will have multiple methods. 


The source for the above can be found in the link here



Decorator Pattern

Definition -

This pattern allows the designer to modify or extend the functionality of an object at run time. The speciality of this is that you can extend the capability of only one of the objects of the class.

Scenario -

    Let us take a scenario of manufacture of cars, the plant wants to modify various class for the same car depending on the order, which means some one might choose fullyloaded, basic and mid.

Based on the above this is these are the classes which we will create
1. An interface called as car. 

package DecoratorPattern;

public interface car {
    
    public void manufacture();

}

2. A basiccar class which will implement the interface car.
package DecoratorPattern;

public class basiccar implements car{

    @Override
    public void manufacture() {
        
        System.out.println("Maufacturing a basic car");
        
    }

}

3. A decorator class which implement car interface.
package DecoratorPattern;

public class decorator implements car {

    car cardemo;
    
    public decorator(car cars) {
        this.cardemo=cars;
    }
    
    @Override
    public void manufacture() {
        
        
        this.cardemo.manufacture();
        
        
    }

}

4. Two concrete decorators called fullyloaded and mid which will extend the decorator class.
fullyloaded.java
package DecoratorPattern;

public class fullyloaded extends decorator {

    public fullyloaded(car cars) {
        super(cars);
    }
    
    public void manufacture() {
        super.manufacture();
        System.out.println("Adding components of a fully loaded car");
    }

}


midlevel.java
package DecoratorPattern;

public class midlevel extends decorator {

    public midlevel(car cars) {
        super(cars);
    }
    
    public void manufacture() {
        super.manufacture();
        System.out.println("Adding components of a mid level car");
    }

}




We will first create a class called car1 and add engine and chassis as two components. Then we will clone this into car2 and display the components.

package DecoratorPattern;

public class decoratordemo {
    
    public static void main(String args[]) {
        
        car midlevelcar=new midlevel(new basiccar());
        midlevelcar.manufacture();
        
    }

}

 
Place to use -
1) When you deal with a system where if you go by normal design can create too much inheritence or sub classes.
2) You would want to add features / or modify an object in runtime.


To be careful about -
1) Since the features are added via decorators too many of these can cause maintainence issues.


The code used above can be found in the link here 



Composite Pattern

Definition -
   
    It is a pattern used when you have objects of different functionalities and you want to build structures using these, but at the same time you want all the objects to be treated in a same way.
This pattern has three components to it -
1) Base components - It is the interface for all objects in the structure.
2) Leaf - one or more base components define a leaf. This is can be called as the building blocks of the structure.
3) Composite - it contains one or more leaf nodes.

Scenario -

    Let us take an example of the construction of a Building.
1) Base components - Make
2) Leaf - Walls, roof, doors, windows
3) Composite - Floor

Based on the above this is these are the classes which we will create
1. A abstract class called Make which have an build funtion.




package CompositePattern;

public abstract class make {
    
    public abstract void build();

}

2. There are leaf objects called walls, roof.

walls.java
 package CompositePattern;

public class walls extends make{

    @Override
    public void build() {
        
        System.out.println("Building walls");
        
    }

}


roof.java
 package CompositePattern;

public class roof extends make{

    @Override
    public void build() {
       
        System.out.println("Building roof");
       
    }

}



3. Construction is a composite object
package CompositePattern;

import java.util.ArrayList;

public class construction extends make{
    
    ArrayList<make> components= new ArrayList<make>();
    

    @Override
    public void build() {
        
        for(make structures: components) {
            structures.build();
        }
        
    }
    
    
    public void addstructure(make component) {
        components.add(component);
    }


}


4. To see the pattern in action use the below code

package CompositePattern;

public class compositepatterndemo {
    
    public static void main(String args[]) {
        
        make wls=new walls();
        make rf=new roof();
        
        construction ctr=new construction();
        ctr.addstructure(wls);
        ctr.addstructure(rf);
        
        ctr.build();
        
    }

}


Place to use -
1) When objects can be made into an hierarchy and the objects can treated in a similar fashion.

Place not to use -
1) When you do not want to make your objects too generic.
2) When you cannot create hierarchy and order objects in it.

To get the code for the above use the link
here


Bridge Pattern

Bridge Pattern

Definition -
    The basis for a bridge is to decouple an abstract class from the place where it is implemented. This means the abstraction should not be binded with the implementation at compile time, rather it should be done at runtime depending on the place it is invoked.

Scenario -
Now lets take a scenario of a factory line which does both production and designing of both hatcback and sedan.
1) In this case we can consider it as two abstract entities, one is vehicle and the other is type. 


vehicle.java
 
package BridgePattern;

public abstract class vehicle {
    
    public type type1;
    public type type2;
    
    public vehicle(type type1, type type2) {
        this.type1=type1;
        this.type2=type2;
    }
    
    public abstract void manufacture();

}


type.java
 
package BridgePattern;

public interface type {
    
    public void manufacture();

}





2) hatcback and sedan are two concrete classes which will implement the vehicle interface.

hatchback.java

package BridgePattern;

public class hatchback extends vehicle {

    public hatchback(type type1, type type2) {
        super(type1, type2);
    }
    
    
    

    @Override
    public void manufacture() {
        System.out.println("Started Manufacturing a hatchback");
        type1.manufacture();
        type2.manufacture();
        
    }

}


sedan.java

package BridgePattern;

public class sedan extends vehicle {

    public sedan(type type1, type type2) {
        super(type1, type2);
    }

    @Override
    public void manufacture() {
        System.out.println("Started Manufacturing a sedan");
        type1.manufacture();
        type2.manufacture();        
    }

}





3) production and designing are two concrete classes which will implement the type interface. 

production.java

package BridgePattern;

public class production implements type {

    @Override
    public void manufacture() {
        
        System.out.println("Started production");
        
    }

}


design.java

package BridgePattern;

public class design implements type {

    @Override
    public void manufacture() {
        
        System.out.println("Started design");
        
    }
    
    

}


4) Lets see how to implement this in a client

bridgedemo.java





package BridgePattern;

public class bridgedemo {

    public static void main(String[] args) {
        
    vehicle v1=new hatchback(new design(),new production());
    v1.manufacture();
    

    }

}


Place to use -
1) When you need abstraction
2) When you do not want to bind the classes at compile time
3) When you want hierarchies to interact with each other

Place not to use -
1) Increases complexity
Did not find any other aspect to this, you are welcome with you suggestions.


The code for this can be found in github in the link here








Adapter Pattern

Definition -

This is a creational pattern. It is also reffered to as Factory of Factories. This helps designers to decouple objects from the implementing systems. Here the abstract factory will have a set of core functionalities which has to be implemented by all the factories which implement them.

Scenario -
Lets take a scenario where in you are designing a software which would display images. The image can be either jpeg / png. In future there can be other format as well where in you would want to implement in an incremental manner.  -

1) There will be an interface called imagerender where we state it can display an image. We will call this imagerender.


 
package AdapterPattern;


public interface imagerender {
    
    public void displayimage(String imagetype, String path);

}




2) Since the feature of the software is to display image of either png or jpeg we will have an image adapter which will perform the action to choose which class to implement. We will call this imageAdapter

package AdapterPattern;

public class imageAdapter implements imagerender{

    Advancedimageprocessor aip;
    
    
    public imageAdapter(String imagetype) {
        
        if(imagetype.equalsIgnoreCase("JPEG")) {
            
            System.out.println("Creating object ");
            
            aip=new jpegimage();
        }
        else if(imagetype.equalsIgnoreCase("PNG")){
            
            System.out.println("Creating object ");
            aip=new pngimage();
        }
        
    }
    
    
    @Override
    public void displayimage(String imagetype, String path) {
        
        if(imagetype.equalsIgnoreCase("JPEG")) {
            System.out.println("displaying object ");
            aip.jpegdisplay(path);
        }
        else if(imagetype.equalsIgnoreCase("PNG")) {
            System.out.println("displaying object ");
            aip.pngdisplay(path);
        }
    }
    

}



3) There will be an interface called advancedimageprocessor which will have the template for the different kinds of imageformat functionalities.

 
package AdapterPattern;

public interface Advancedimageprocessor {
    
    public void jpegdisplay(String path);
    public void pngdisplay(String path);

}


4) There will be two concrete factories called jpegimage and pngimage which will provide the actual implementation functionalities.

 jpegimage.java

 
package AdapterPattern;

public class jpegimage implements Advancedimageprocessor {
    
    public jpegimage() {
        System.out.println("Inside class jpeg image");
    }

    @Override
    public void jpegdisplay(String path) {
        
        System.out.println("Displaying jpeg image from the path: "+path);
        
    }

    @Override
    public void pngdisplay(String path) {
        // TODO Auto-generated method stub
        
    }

    

}


pngimage.java 

package AdapterPattern;

public class pngimage implements Advancedimageprocessor {
    
    
    public pngimage() {
        System.out.println("Inside class png image");
    }

    @Override
    public void jpegdisplay(String path) {
        
        
    }

    @Override
    public void pngdisplay(String path) {
        
        System.out.println("Displaying png image from the path: "+path);
        
    }
    
}



5) We will have a class called imagedisplay which call the imageAdapter.

 
package AdapterPattern;

public class imageDisplay implements imagerender{

    imageAdapter iA;
    
    public imageDisplay() {
        System.out.println("Inside imageDisplay");
    }
    
    @Override
    public void displayimage(String imagetype, String path) {
        
        System.out.println("Displaying "+ imagetype+" in path "+path);
        
        iA=new imageAdapter(imagetype);
        iA.displayimage(imagetype, path);
        
    }
    
    

}


6) Finally we will have a client called adapterClient which will be calling either PNG or JPEG formats.

package AdapterPattern;

public class adapterClient {

    public static void main(String[] args) {
        
        imageDisplay iD = new imageDisplay();
        iD.displayimage("PNG", "C:\test1");
        //iD.displayimage("JPEG", "C:\test2");

    }

}


Place to use -
1. If you require middleman between two modules and at the same time you require to ensure it is a flexible design, I cannot say it is a scalable design (You can differ on this).
2. When you want to provide temporary fix the interaction between two modules till you figure out a permanent design.
3. Although you might consider this when you want to use a plug in kind of feature, but again be careful.


Place not to use -
1. Do not use this if you have other options because debugging is quiet an headache.
2. It is not a neat design.
3. Makes maintainence of the code a nightmare.


The code for this is available in github link here