Thursday, April 26, 2012

Structural Patterns - 3.Composite Pattern

The Composite Pattern is a very simple pattern to represent a complex structure of data. Whenever in an application, if we need to design a tree structure with leaf and nodes then this pattern could be a right candidate.

This pattern treats both the nodes and the leaves in the same way as they are the parts of the same tree.A parent-child hierarchy of many levels is a complex task to handle through the code. A child can have many children so that it will become a parent by itself.

Some children may not become a parent as they may not have any children on their own. This type of relationship can be gone to the depth of any level (ex:-parent/child generations together).

Having a design to maintain or accomodate such complex structure is a hard task. Thanks to Composite pattern which makes our life easy in the above scenario.Let us consider the below class diagram explaining the Composite Pattern,


Here, we have a generic Human Interface having two implementations
a) Child
b) Parent


The child class would be a leaf node which won't have any furthur nodes attached to it whereas a parent class is composed of a list of nodes of type Human.

Again those nodes may be either parent or child. This pattern appears recursively so that we can handle theparent and child objects to any number of generations.

Find below the structure of sample data which operates over the composite pattern,



Following code snippet will explain the above mentioned structure,
 public static void main(String[] args) {
 
  Parent one=new Parent("Gen1Parent");
  Human two=new Child("Gen2Child");
  Parent three=new Parent("Gen2Parent");
  Parent four=new Parent("Gen3Parent");
  Human five=new Child("Gen3Child");
  three.add(five);
  three.add(four);
  one.add(three);
  one.add(two);


  printItems(one); //Method to print all the values from the Tree
 
 }
 

Following code snippet will show how to iterate over the list of values in order to fetch the nodes and their leaves,

 public static void printItems(Parent parent){
         System.out.println(parent.getName());
  for(Human human:parent.getChildren()){
   if(human.getType().equals("Parent")){
   
    printItems((Parent)human);
   }else{
    System.out.println(human.getName());
   }
  }
 }

Tuesday, April 24, 2012

Structural Patterns - 2.Bridge Pattern

There are scenarios where we may need to deal with different combinations of abstractions and their implementations.

Bridge pattern helps us to seperate/decouple the abstraction and its implementation. We can use composition in order to associate an abstraction to a particular implementation. This will help us to design an extensible application.

Here, the abstractions and implementations where nowhere related to each other.

For example, We are having some abstractions of Pen like fountain pen, ball point pen,etc. As an implementation we can have some documents or contents like poem,essay,etc can be written out of a Pen.

Here, we compose Content to the Pen class so that we can use any type of pen to draft any type of content. The following class diagram explains this pattern,







Code to associate an abstraction to an implementation dynamically,


  Pen[] pens=new Pen[]{new BallPointPen(new Essay()),
                                                                 new FountainPen(new Poem())};
  for(Pen pen:pens){  
         System.out.println(pen.write());
  }

In the above code snippet, we dynamically associate the Essay and Poem instances to BallPointPen and FountainPen instances respectively.


In the BallPointPen/FountainPen class, we can handle this association as follows,


            public BallPointPen(Content content) {  
                      this.content=content;
            }
           @Override
           public String write() {  
                      return content.createContent()+" with BallPoint Pen";
           }

Thursday, April 19, 2012

Structural Patterns - 1.Adapter Pattern

So far, we discussed about the ways of creating an object and patterns involved during object creation.

Next we are going to see about the Structural patterns. They mostly deal with the way the classes or interfaces or represented or related. The influence of class structures on achieving a functionality will be widely discussed with a set of patterns.

Adapter Pattern

This is one among the most frequently used Design Patterns. The main benefit in going for the Adapter pattern, is to establish proper communication between two or more incompatible interfaces. In otherwords, adapter makes two different interfaces communicate each other.

There are two types of Adapters,
a) Class Adapters and
b) Object Adapters

Class Adapters

Consider, there are two different interfaces requires communication between each other. The Adapter class will inherit both the interfaces and overrides the implementation by custom code. Message from one interface will be taken and customized in such a way the other interface could process it.

A simple example of Class Adapters can be seen below,



In the above design, we want to transfer some data from a USB device to an HDMI device. So, we defined an Adapter class USBHDMIAdapter by inheriting both USBSource and HDMISource.

While writing the implementation for the method getHDMIData(), we internally fetch the USBData and perform customizations in order to make the data compatible with HDMI. Finally return the data back to the HDMI Source.

Sample code snippet for better understanding,

In the Adapter class we write our implementation for the getHDMIData() as follows,
public String getHDMIData() {
String hdmiData=getData().replace("USB", "HDMI");
return hdmiData;
}


and in the Client class we can invoke the Adapter as stated below,

USBSource usbSource=new USBSource();
usbSource.setData("USB Movie - 123");

HDMISource hdmiSource=new USBHDMIAdapter(usbSource);
System.out.println(hdmiSource.getHDMIData());


Object Adapters

They are very much similar to the Class Adapters but instead of generalization we use composition. We compose the USBSource object and write implementation for the HDMISource with our custom code.

Following design explains the Object Adapter pattern,



The source code for defining the Object Adapter may look as specified below,

class USBHDMIAdapter implements HDMISource{

private USBSource usbSource;

public USBHDMIAdapter(USBSource source) {
this.usbSource=source;
}

@Override
public String getHDMIData() {
String hdmiData=usbSource.getData().replace("USB", "HDMI");
return hdmiData;
}

}