Purpose of Composite Design Pattern

"Compose objects into tree structure to represent part-whole hierarchies. 

Composite lets client treat individual objects and compositions of objects uniformly".

Composite design pattern treats each node in two ways-CompositeĀ orĀ leaf. 
Composite means it can have other objects below it. Leaf does not have objects below it

Component
declares interface for objects in composition.
implements default behavior for the interface common to all classes as appropriate.
declares an interface for accessing and managing its child components.
Leaf
represents leaf objects in the composition. A leaf has no children.
defines behavior for primitive objects in the composition.
Composite
defines behavior for components having children.
stores child components.
implements child related operations in the component interface.
Client
manipulates objects in the composition through the component interface.

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


interface Employee {

 public void add(Employee employee) throws Exception;
 public void remove(Employee employee);
 public Employee getChild(int i);
 public String getName();
 public double getSalary();
 public String getDesignation();
 public void print();
}


class Director implements Employee{

 private String name;
 private double salary;

 public Director(String name,double salary){
 this.name = name;
 this.salary = salary;
 }

 List<Employee> employees = new ArrayList<Employee>();
 public void add(Employee obj) throws Exception{
 String c_name = obj.getClass().getName();
 if(c_name.equalsIgnoreCase("Manager"))
 {
 employees.add(obj);
 }
 else
 {
 throw new Exception("non Manager not allowed to add");
 }
 
 }

 public Employee getChild(int i) {
 return employees.get(i);
 }

 public String getName() {
 return name;
 }

 public double getSalary() {
 return salary;
 }

 public String getDesignation(){
 return "Director";
 }
 public void print() {
 System.out.println("-------------");
 System.out.println("Name ="+getName());
 System.out.println("Salary ="+getSalary());
 System.out.println("-------------");

 Iterator<Employee> employeeIterator = employees.iterator();
 while(employeeIterator.hasNext()){
 Employee employee = employeeIterator.next();
 employee.print();
 }
 }

 public void remove(Employee employee) {
 employees.remove(employee);
 }
 }


class Manager implements Employee{

 private String name;
 private double salary;

 public Manager(String name,double salary){
 this.name = name;
 this.salary = salary;
 }

 List<Employee> employees = new ArrayList<Employee>();
 public void add(Employee employee) {
 employees.add(employee);
 }

 public Employee getChild(int i) {
 return employees.get(i);
 }

 public String getName() {
 return name;
 }

 public double getSalary() {
 return salary;
 }

 public String getDesignation(){
 return "Manager";
 }
 public void print() {
 System.out.println("-------------");
 System.out.println("Name ="+getName());
 System.out.println("Salary ="+getSalary());
 System.out.println("-------------");

 Iterator<Employee> employeeIterator = employees.iterator();
 while(employeeIterator.hasNext()){
 Employee employee = employeeIterator.next();
 employee.print();
 }
 }

 public void remove(Employee employee) {
 employees.remove(employee);
 }
}


class Developer implements Employee{

 private String name;
 private double salary;

 public Developer(String name,double salary){
 this.name = name;
 this.salary = salary;
 }
 public void add(Employee employee) {
 //this is leaf node so this method is not applicable to this class.
 }

 public Employee getChild(int i) {
 //this is leaf node so this method is not applicable to this class.
 return null;
 }

 public String getName() {
 return name;
 }

 public double getSalary() {
 return salary;
 }

 public String getDesignation(){
 return "Developer"; 
 }
 
 public void print() {
 System.out.println("-------------");
 System.out.println("Name ="+getName());
 System.out.println("Salary ="+getSalary());
 System.out.println("-------------");
 }

 public void remove(Employee employee) {
 //this is leaf node so this method is not applicable to this class.
 }

 }
 

public class CompositeEg {
 public static void main(String[] args) {
 try
 {
 Employee dir1 = new Director("dir1", 80000);
 Employee manager1=new Manager("mgr1",25000);
 
 Employee emp1=new Developer("dev1", 10000);
 Employee emp2=new Developer("dev2", 15000);
 
 manager1.add(emp1);
 manager1.add(emp2);
 
 dir1.add(manager1);
 
 Employee gManager=new Manager("mgr2", 50000);
 Employee emp3=new Developer("dev3", 20000);
 
 gManager.add(emp3);
 gManager.add(manager1);
 
 dir1.add(gManager);
 dir1.print();
 
 dir1.add( new Developer("ldev",19000));
 
 System.out.println("Designation: "+gManager.getDesignation());
 }catch(Exception e)
 {
 e.printStackTrace();
 }
 }
}

Design Pattern Free PDF

Chain of Responsibility Design Pattern

Below is an example of Chain of Responsibility Design Pattern

One of the best example where Chain of Responsibility Design Pattern can be applied is below.
Say if you want to withdraw 2200 Rs, and ATM has 1000, 500 and 100 rupee notes.
As per chain of responsibility the request would be sent to object that dispenses 1000 rs note.
If 1000 rupee notes are NOT available then it would be sent to an object that dispenses 500 rs note.
The 500Rs object decides to dispense 4 notes and then 100 rs object would be asked to handle the rest.
* Advantage is, eventhough there are no 1000 rs not available, your request would be still handled by other objects like 500 and 100.

class Request{
	int value;
	String desc;
	
	public Request(int value, String desc)
	{
		this.value = value;
		this.desc = desc;
	}
	
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public String getDesc() {
		return desc;
	}
	public void setDesc(String desc) {
		this.desc = desc;
	}	
}

abstract class Handler{
	Handler scsr;
	
	public void setSuccessor(Handler scsr)
	{
		this.scsr = scsr;
	}
	
	public abstract void handleRequest(Request rqs);
}

class ConcreteHandlerOne extends Handler{
	public void handleRequest(Request rqs)
	{
		if(rqs.getValue()<0)
		{
			System.out.println(" Handling Request details<0:"+rqs.getValue()+" "+rqs.getDesc());
		}
		else
		{
			scsr.handleRequest(rqs);
		}
	}
}

class ConcreteHandlerTwo extends Handler{
	public void handleRequest(Request rqs)
	{
		if(rqs.getValue()>0)
		{
			System.out.println("Handling Request details>0:"+rqs.getValue()+" "+rqs.getDesc());
		}
		else
		{
			scsr.handleRequest(rqs);
		}
	}
}

class ConcreteHandlerThree extends Handler{
	public void handleRequest(Request rqs)
	{
		if(rqs.getValue()==0)
		{
			System.out.println("Handling Request details==0:"+rqs.getValue()+" "+rqs.getDesc());
		}
		else
		{
			scsr.handleRequest(rqs);
		}
	}
}

public class CoREg {
	public static void main(String[] args) {
		Handler h1 = new ConcreteHandlerOne();
		Handler h2 = new ConcreteHandlerTwo();
		Handler h3 = new ConcreteHandlerThree();
		
		h1.setSuccessor(h3);
		h3.setSuccessor(h2);
		
		Request req = new Request(25, "Test Purpose");
		h1.handleRequest(req);
		
		Request reqn = new Request(-25, "Test Purpose");
		h1.handleRequest(reqn);
	}
}

Facade Design Pattern

A Design Pattern is a documented and prooven design solution, which can be used to solve commonly occurring Design Problems.

A Facade Design Pattern is providing Simple, Single Unified interface to a set of classes. Below is an example of the same.

As shown in below diagram, an Application is directly dependent on Display, FileSystem, Networking etc….we are assuming each of these services are provided by corresponding class. Without using Facade Pattern, Application is directly dependent on the classes.

But by re designing above solution by using facade Pattern, Application is not directly dependent on each of individual classes, Hence any change in the public methods exposed by the individual class or change of class, may not directly impact Application. If any changes in the individual classes, changes need to be performed in the UnifiedAPI, and hence Application need not be changed.

Facade Pattern
Facade Pattern



class FileSystem{

   public void readFile() {
      System.out.println("readFile() in FileSystem");
   }
}

class Network {

   public void sendData() {
      System.out.println("sendData() in Network");
   }
}


class Display {

   public void draw() {
      System.out.println("draw() in Display");
   }
}

class AppLifeCycle {

   public void startApp() {
      System.out.println("startApp() in AppLifeCycle");
   }
}

interface OSAPI{
    public void readFileOS();
    public void sendDataOS();
    public void startAppOS();
    public void drawOS(); 
}

class FacadeClass implements OSAPI{
      public void readFileOS(){
          new FileSystem().readFile();
      }
      
    public void sendDataOS(){
            new Network().sendData();
    }
    
    public void startAppOS(){
        new AppLifeCycle().startApp();
    }
    
    public void drawOS(){
        new Display().draw();
    }
}

public class FacadePattern1 {
   public static void main(String[] args) {
      FacadeClass obj = new FacadeClass();

      obj.drawOS();
      obj.readFileOS();
      obj.sendDataOS();
      obj.startAppOS();
   }
}

Advantage of Decorator Design Pattern

Decorator design pattern modifies behavior of an object during runtime. At the same time other instances of the same class will not be affected by this, only individual objects will get modified behavior(added by Decorator classes). Decorator pattern uses abstract classes or interface with composition to implement.

Generally to add functionality to an existing object, inheritance or composition can be used. But disadvantage is that would be Compile time decision.This compile time decision, has a number of drawbacks, as specified below.

Suppose you have a Car class. Then in some place you want a Car with air bags, so you subclass Car and create AirbagCar class. And in some other place you want a tube less tyres for the Car. So you subclass again and create TubelessTyresCar. Well, now in some place you want tube less tyres and air bags both. None of the previous two sub classes have both capability. So you need to create a 3rd one. When creating a AirbagTubelessTyreCar you are actually duplicating the effort. You don’t need this class if you have any way to compose the capability of previous two. Well, things can go worse and these may lead to unnecessary class explosion.

Basically, by using decorator pattern you can add any number of additional responsibility to object at runtime which you cannot achieve by subclassing without potentially damaging your code structure.

The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime.

Purpose of decorator pattern is to dynamically add additional behaviour/functionality, which is of course not possible at design time.

The decorator pattern is an alternative to subclassing. Subclassing adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at runtime for individual objects.

Below is an example of Decorator Design Pattern

public interface Car{
public String driveCar();
}
public class SimpleCar implements Car {

  @Override
  public String driveCar() {
    return "drive SimpleCar";
  }

}

Below is decorator class, which is core of decorator design pattern. Instance is assigned dynamically at the creation of decorator using its constructor. Once assigned that instance method will be invoked.

abstract class CarDecorator implements Car {

  protected Car specialCar;

  public CarDecorator(Car specialCar) {
    this.specialCar = specialCar;
  }

  public String driveCar() {
    return specialCar.driveCar();
  }
}

public class AirbagCarDecorator extends CarDecorator {

  public AirbagCarDecorator(Car specialCar) {
    super(specialCar);
  }

  public String driveCar() {
    return specialCar.driveCar() + addAirbags();
  }

  private String addAirbags() {
    return " with Air bags, ";
  }
}

public class TubelessCarDecorator extends CarDecorator {

  public TubelessCarDecorator(Car specialCar) {
    super(specialCar);
  }

  public String driveCar() {
    return specialCar.driveCar() + addTubeless();
  }

  private String addTubeless() {
    return " with Air bags, ";
  }
}

public class MyDemo{
  public static void main(String args[])
  {
   SimpleCar obj =new TubelessCarDecorator(new AirbagCarDecorator(new SimpleCar()));
   System.out.println(obj.driveCar());
  }
}

In java.io package Decorator pattern has been widely used, as shown below
#1.java.io.BufferedReader;
java.io.FileReader;
java.io.Reader;
#2.java.io.SequenceInputStream
java.io.FileInputStream
java.io.InputStream
java.io.DataInputStream

You may also like to read:
How to Control maximum number of objects
How to combine two or more InputStreams into single InputStream
Design Pattern used for JDBC

What is Proxy Design Pattern?

Provide a surrogate or placeholder for another object. This Place holder object provides some advantages, few are as below.

#1. to Access Remote Object.
#2. to control access of few methods of original object.
#3. it may be costly(consumes more memory or time) to use original object.
…and many more.

Below is an example, of using place holder object of VideoProxy instead of original Video object.

As shown in example below, object of Video class loads video file, even to display thumb nail. As known it consumes more memory to load multiple video thumb nails, in a single screen.

To keep memory consumption minimal, ProxyVideo has been implemented, which displays an Image to display thumb nail. And the video file is loaded, only when user want to play the video, that too only the specific video file which the user opted to view, will be loaded to play.

public interface IVideo {
   void displayThumbnail();
   void playVideo();
}

public class Video implements Image {

   private String fileName;

   public Video(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void displayThumbnail() {
      loadVideoFromStorage();
      System.out.println("Displaying Thumbnail of " + fileName);
   }

   private void loadVideoFromStorage(){
      System.out.println("Loading actual video... " + fileName);
   }

   @override
   public void playVideo()
   {
      loadVideoFromStorage();
   }
}

public class ProxyVideo implements IVideo{

   private Video objVideo;
   private String fileName;

   public Video(String fileName){
      this.fileName = fileName;
   }

   @Override
   public void displayThumbnail() {
      String thumbnail_name = fileName+"_thumbnail.jpg";
      System.out.println("Display Thumbnail Image..."+thumbnail_name);
   }

   @Override
   public void playVideo() {
      objVideo = new Video(fileName);
      objVideo.playVideo();
   }
}

In this example, Aggregation is used(Read more on Composition and Aggregation), instead inheritance can be used here.

Difference between Proxy and Adapter Pattern

Adapter Pattern is to change the interface of class A to the expectations of another class B. The typical implementation is a wrapper class or set of classes.

Proxy Pattern is similar, but the purpose is different. The purpose of the proxy pattern is to create a stand-in for a real resource. As already briefed, this stand-in is required as the actual object is remotely located or it is expensive to create actual object or you want to give controlled access to methods of actual class, etc…

You may also like to read:
What is Factory Design Pattern
How to implement Singleton Design Pattern
Can Adapter Pattern use Composition
Adapter Pattern using Inheritance

Factory method Design Pattern in Java

In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

Advantages of Factory Pattern

1.It can be used to unify the creation of objects sharing a commonality, e.g. in caching: CacheFactory -> Memcache, Filecache, … Working with each cache is similar, but setting up different caching strategies may differ vastly. When using the factory method you can switch between different caching strategies more easily, at best by just chaning one line of code factory(“Memcache”, options),without having to worry about the intricacies of the specific backend;
2.Improves loose Coupling

Also, disadvantage of Factory Pattern is loose coupling by means of additional objects results in decreased performance.

Below is an example of Factory Design Pattern.

public interface ImageReader {
    public DecodedImage getDecodedImage();
}

public class GifReader implements ImageReader {
    public GifReader( InputStream in ) {
        // check that it's a gif, throw exception if it's not, then if it is decode it.
    }

    public DecodedImage getDecodedImage() {
       return decodedImage;
    }
}

public class JpegReader implements ImageReader {
    public JpegReader( InputStream in) {
    }

    public DecodedImage getDecodedImage() {
      return decodedImage;
    }
}

public class PngReader implements ImageReader {
    public PngReader( InputStream in) {
    }

    public DecodedImage getDecodedImage() {
      return decodedImage;
    }
}

public class ImageFactory {

   //use getShape method to get object of type shape
   public static ImageReader getImageReader(String fileName){
      //open file and get type of file
      String file_type = ;
      if(file_type.equalsIgnoreCase("GIF")){
         return new GifReader();

      } else if(file_type.equalsIgnoreCase("JPEG")){
         return new JpegReader();

      } else if(file_type.equalsIgnoreCase("PNG")){
         return new PngReader();
      }

      return null;
   }
}

public class MyImageDemo{
   public static void main(String args[])
   {
       String image_file_name = "abc.gif";
       ImageReader ir = ImageFactory.getImageReader(image_file_name);
       DecodedImage di = ir.getDecodedImage();

       //DecodedImage object may be used to display image,etc...
   }
}

Difference between Composition and Aggregation

In Object oriented languages, Composition, Aggregation and Inheritance are the most common relationships exist between classes.

Composition in Java

Composition is has-a relationship. Also sometimes referred as non-separable part of the whole.
Composition is more stronger relationship compared to Aggregation. Here composed object cannot exist without composing object, and both objects have same life time.

As shown in below code snippet, object of B(i..e obj) cannot exist without object of B. Object of B gets created only along with object of A. Also obj1 does not continue to exist, after object of A gets destroyed.

class A{
B obj;
//… other data members and methods, of class A
}

Aggregation

Aggregation is also a has-a relationship. Also sometimes referred as separable part to whole.
Aggregation is a weaker relationship compared to Composition.
As shown in below code snippet, object of D(i..e obj1) can exist even before object of C gets created. Also obj1 may continue to exist even after object of C is destroyed.

class C{
D obj1;
//… other data members and methods, of class C
}
Composition is Strong Has-A relationship Aggregation is a Weak Has-A relationship.

To understand difference between Composition and Aggregation, lets us take an example of a College with few Departments, and each Department with Lecturers.

aggregation and composition
aggregation and composition

Relationship between College and Department is Composition, and relationship between Department and Lecturer is Aggregation.

class College
{
  private List depts;

  public College()
  {
    depts.add(new Department("Computer Dept"));
    depts.add(new Department("Electrical Dept"));
    depts.add(new Department("Electronics Dept"));
  }

  //...other methods in College class
}

A Department cannot exist without College, hence difference between them is Strong and hence Composition.
When College no more exist, Department cannot exist.

Relationship between Department and Lecturer can be Aggregation, as it is weaker. A Lecturer can exist, even before Department exist. And Lecturer may continue to exist even after Department gets destroyed.

class Department
{
  private Lecturer my_obj;

  public void setLecturer(Lecturer lect)
  {
    my_obj = lect;
  }
  //...other methods in Department class
}

Adapter Pattern with Composition

Adapter pattern makes two incompatible interfaces to work together. These Incompatible interfaces are not designed and developed for one another, and assuming they have evolved separately.

Adapter Pattern can be implemented using any of the below.

  1. Inheritance
  2. Composition

Implementing Adapter pattern with Composition

In below example NewArithmetic and Arithmetic are classes, which are incompatible. And they have been designed separately, and one is not designed for another.

Now ArithmeticAdapter is implemented to make NewArithmetic and Arithmetic classes, compatible with each other.

Here ArithmeticAdapter contains Adaptee, i..e NewArithmetic

public class NewArithmetic
{
    public float add_values(float val1, float val2)
    {
        return val1+val2;
    }

    public float sub_values(float val1, float val2)
    {
        return val1-val2;
    }
}

public class ArithmeticAdapter{
    private NewArithmetic obj;

    public ArithmeticAdapter()
    {
        obj = new NewArithmetic();
    }

    public int add_adptr(int val1, int val2)
    {
        return (int)obj.add_values(val1,val2);
    }

    public int sub_adptr(float val1, float val2)
    {
        return (int)obj.sub_values(val1,val2);
    }
}

public class Arithmetic
{
    public void add(int val1,int val2)
    {
        System.out.println("Added Result:"+new ArithmeticAdapter().add_adptr(val1, val2));
    }

    public void sub(int val1,int val2)
    {
        System.out.println("Subtraction Result:"+new ArithmeticAdapter().sub_adptr(val1, val2));
    }
}

public class AdapterComposition {
    public static void main(String[] args) {
        Arithmetic obj = new Arithmetic();

        obj.add(23, 42);
        obj.sub(46, 21);
    }

}

Output:
Added Result:65
Subtraction Result:25

You may also like to read: Adapter Pattern with Inheritance

Adapter Pattern with Inheritance

Adapter pattern makes two incompatible interfaces to work together. These Incompatible interfaces are not designed and developed for one another, and assuming they have evolved separately.

Adapter Pattern can be implemented using any of the below.

  1. Inheritance
  2. Composition

Implementing Adapter pattern with Inheritance

In below example NewArithmetic and Arithmetic are classes, which are incompatible. And they have been designed separately, and one is not designed for another.

Now ArithmeticAdapter is implemented to make NewArithmetic and Arithmetic classes, compatible with each other.

Here ArithmeticAdapter inherits from Adaptee, i..e NewArithmetic

public class NewArithmetic
{
    public float add_values(float val1, float val2)
    {
        return val1+val2;
    }

    public float sub_values(float val1, float val2)
    {
        return val1-val2;
    }
}

public class ArithmeticAdapter extends NewArithmetic{
    public int add_adptr(int val1, int val2)
    {
        return (int)add_values(val1,val2);
    }

    public int sub_adptr(float val1, float val2)
    {
        return (int)sub_values(val1,val2);
    }
}

public class Arithmetic
{
    public void add(int val1,int val2)
    {
        System.out.println("Added Result:"+new ArithmeticAdapter().add_adptr(val1, val2));
    }

    public void sub(int val1,int val2)
    {
        System.out.println("Subtraction Result:"+new ArithmeticAdapter().sub_adptr(val1, val2));
    }
}

public class AdapterPattern {
    public static void main(String[] args) {
        Arithmetic obj = new Arithmetic();

        obj.add(23, 42);
        obj.sub(46, 21);
    }

}

Output:
Added Result:65
Subtraction Result:25

You may also like to read: Adapter Pattern with Composition

What is Singleton Design Pattern

Singleton Design Pattern ensures that maximum one object can exist for a class. Below are steps you need to make a class Singleton.

1. Make all constructors private.
2. Add a static method, which creates and returns object of the class.
3. Add a static data member of its type, so that it can be returned, if object already exists.
4. Add a static int data member, which stores number of objects currently exists(whose value will be either 0 or 1, always)
5. In static method(added above in step 2), if number of objects is zero, create new object(by invoking private constructor), and return it. If number of objects is one, return existing object, without creating new object.

Below is example Design pattern code.
public class Abc {

private static int objCount = 0;

//step 3
private static Abc obj;

//step 1
private Abc(){ System.out.println(“This is Constructor”);}

//step 2
public static Abc createInstance(){
if(objCount ==0)
{
objCount++;
obj= new Abc();
System.out.println(“object created”);
}
else
{
System.out.println(“Returning existing object”);
}

return obj;
}

}

public class MySingleton {
public static void main(String[] args) {

Abc nc = Abc.createInstance();
Abc nc1 = Abc.createInstance();
Abc nc2 = Abc.createInstance();
}
}

Output:
object created
Returning existing object
Returning existing object