Showing posts with label Java Design Patterns. Show all posts
Showing posts with label Java Design Patterns. Show all posts

Saturday, September 29, 2012

Builder design pattern in java

Builder design pattern allows to create complex object step by step and also enforces a process to create an object as a finished product.Construction of object should be such that same construction process can create different representations.Director controls the construction of object and only director knows what type of object to create.

For example, You can consider printing of a book.Printing of a book involves various steps such as printing table of content,preface,introduction,chapters and conclusion.Finally you will get complete book object. With the help of same above process,you can print books with different properties.
 
As described by Gof:
"Separate the construction of a complex object from its representation so that the same construction process can create different representations"

Generic UML diagram for builder design pattern:

Elements:

  • Builder
    • specifies an abstract interface for creating parts of a product object.
  • ConcreteBuilder
    • constructs and assembles parts of the product by implementing the builder interface.
    • defines and keeps track of the representation it creates.
    • provides an interface for retrieving the product.
  • Director
    • constructs an object using builder interface.
  • Product
    • represents the complex object under construction.ConcreteBuilder builds the product's internal representation and defines the process by which it is assembled.
    • includes classes that define the constituent parts,including interfaces for the assembling the parts into final result.

When to use it:

  • Object creation algorithms should be independent of system.
  • New creation algorithm can be added without changing core code.
  • The construction process must allow different representations for the object that' s contructed.
  • Runtime control over creation process is required.

WorkFlow:

  • The client creates the director object and configures it with the desired builder object.
  • Director notifies builder whenever a part of product should be built.
  • Builder handles requests from the director and adds parts to the product.
  • The clients retrieves the product from builder.

Example:

You can consider priniting of a book.Printing of a book involves various steps such as printing table of content,preface,introduction,chapters and conclusion.Finally you will get complete book object. With the help of same above process,you can write books with different properties.  BookWriter will instruct bookBuilder to print book in steps and return final book object.

Comparing to generic UML diagram of builder pattern:
  • BookBuilder(Builder)
  • TechnicalBookBuilder(ConcreteBuilder)
  • FictionalBookBuilder(ConcreteBuilder)
  • BookWriter(Director)
  • Book(Product)
Java codes for above classes:
Following class is our product class.Object of this class will be returned by builder.

Book.java (Product):
package org.arpit.javapostsforlearning.designpatterns;

public class Book {

String introduction;
String tableOfContent;
String preface;
String chapters;
String glossary;

public void setIntroduction(String introduction) {
this.introduction = introduction;
}
public void setTableOfContent(String tableOfContent) {
this.tableOfContent = tableOfContent;
}
public void setPreface(String preface) {
this.preface = preface;
}
public void setChapters(String chapters) {
this.chapters = chapters;
}
public void setGlossary(String glossary) {
this.glossary = glossary;
}
}
Following interface is our builder interface.Builder interface provides steps or process.Here we have five steps-buidTableOfContent,buildPreface,buildIntroduction,buildChapters,buildGlossary.It also has method to return book(product) object. 
BookBuilder.java (Builder):
package org.arpit.javapostsforlearning.designpatterns;

public interface BookBuilder {

public void buildTableOfContent();
public void buildPreface();
public void buildIntroduction();
public void buildChapters();
public void buildGlossary();
public Book getBook();
}
Following class is our first implementation of builder interface.We are having multiple concrete builder class to support  same construction process creating multiple representations.

TechnicalBookBuilder.java(ConcreteBuilder):
package org.arpit.javapostsforlearning.designpatterns;

public class TechnicalBookBuilder implements BookBuilder{
private Book book;

public TechnicalBookBuilder()
{
book=new Book();
}
public void buildTableOfContent() {
System.out.println("printing technical table of content");
book.setTableOfContent("technical table of content");
}

public void buildPreface() {
System.out.println("printing preface");
book.setTableOfContent("preface");
}
public void buildIntroduction() {
System.out.println("printing technical introduction");
book.setTableOfContent("technical introduction");
}

public void buildChapters() {
System.out.println("printing technical chapters");
book.setChapters("technical chapters");
}

public void buildGlossary() {
System.out.println("printing technical glossary");
book.setGlossary("Technical glossary");
}

public Book getBook() {
return book;
}
}

Following class is our second implementation of builder interface.

FictionalBookBuilder.java(ConcreteBuilder):
package org.arpit.javapostsforlearning.designpatterns;

public class FictionalBookBuilder implements BookBuilder{
private Book book;

public FictionalBookBuilder()
{
book=new Book();
}
public void buildTableOfContent() {
System.out.println("printing fictional table of content");
book.setTableOfContent("fictional table of content");
}

public void buildPreface(){
System.out.println("printing preface");
book.setTableOfContent("preface");
}
public void buildIntroduction() {
System.out.println("printing fictional introduction");
book.setTableOfContent("fictional introduction");
}

public void buildChapters() {
System.out.println("printing fictional chapters");
book.setChapters("fictional chapters");
}

public void buildGlossary() {
System.out.println("printing fictional glossary");
book.setGlossary("Fictional glossary");
}

public Book getBook() {
return book;
}

}

Following class is our director class which will instructs BookBuilder to print parts of book and return final book object
BookWriter.java(Director):
package org.arpit.javapostsforlearning.designpatterns;
public class BookWriter {

BookBuilder bookBuilder;

public BookWriter(BookBuilder bookBuilder) {
super();
this.bookBuilder = bookBuilder;
}

public Book getBook()
{
return this.bookBuilder.getBook();
}

public void printBook()
{
this.bookBuilder.buildTableOfContent();
this.bookBuilder.buildPreface();
this.bookBuilder.buildIntroduction();
this.bookBuilder.buildChapters();
this.bookBuilder.buildGlossary();
}
}
BuilderDesignPatternMain.java:
package org.arpit.javapostsforlearning.designpatterns;
public class BuilderDesignPatternMain {


public static void main(String[] args) {

System.out.println(Printing technical book:");
BookBuilder technialbookBuilder=new TechnicalBookBuilder();
BookWriter technicalBookWriter=new BookWriter(technialbookBuilder);
technicalBookWriter.printBook();
Book technicalbook=technicalBookWriter.getBook();
System.out.println("Technical Book Printed:"+technicalbook);
System.out.println("******************************************");
System.out.println(Printing fictional book:");
BookBuilder fictionalbookBuilder=new FictionalBookBuilder();
BookWriter fictionalBookWriter=new BookWriter(fictionalbookBuilder);
fictionalBookWriter.printBook();
Book fictionalbook=fictionalBookWriter.getBook();
System.out.println("Fictionalbook book printed:"+fictionalbook);
}
}
For printing technical book,we have configured bookWriter object with technicalBookBuilder.BookWriter instructed to technicalbookbuilder to print book and return final book object.Same is true for fictional book.So with help of same construction process,we have printed two kinds of book.i.e. technical and fictional.
Output:
Printing technical book:
printing technical table of content
printing preface
printing technical introduction
printing technical chapters
printing technical glossary
Technical Book printed:org.arpit.javapostsforlearning.designpatterns.Book@1888759
******************************************
Printing fictional book:
printing fictional table of content
printing preface
printing fictional introduction
printing fictional chapters
printing fictional glossary
Fictionalbook book printed:org.arpit.javapostsforlearning.designpatterns.Book@1f1fba0 

References:The Gang of Four (GoF) book

Friday, September 28, 2012

Proxy design pattern in java

Proxy design pattern allows you to create a wrapper class over real object.Wrapper class which is proxy,controls access to real object so in turn you can add extra functionalities to real object without changing real object's code.

As described by GoF:
"Provide a surrogate or placeholder for another object to control access over it."

Real life example may be proxy server used in IT companies for internet access.It blocks access to social networking sites like facebook,twitter and other contents which are not work related.

When to use it:

Proxy is required whenever there is need for more sophisticated or versatile reference to an object than a simple pointer.Here are some situations when proxy pattern is applicable.
  1. A remote proxy provides a local representative for an object in a different address space.Providing interface for remote resources such as web service or REST resources.
  2. A virtual proxy creates expensive object on demand.
  3. A protection proxy controls access to the original object.Protection proxies are useful when objects should have different access rights.
  4. A smart reference is a replacement for a bare pointer that performs additional actions when an object is accessed.
  5. Adding a thread-safe feature to an existing class without changing the existing class's code. 

UML diagram for proxy design pattern:

Elements:

  • Proxy
    • maintains a reference that lets the proxy access the real subject.Proxy may refer to a subject if the RealSubject and Subject interface are the same.
    • provides an interface identical to Subject's so that proxy can be substituted for the real subject.
    • controls access to the real subject and may be responsible for creating and deleting it.
  • Subject
    • defines the common interface for RealSubject and proxy so that a Proxy can be used anywhere a RealSubject is expected.
  • RealSubject
    • defines the real object that proxy represents. 

WorkFlow:

Proxy forwards request to RealSubject when appropriate ,depending on the kind of proxy.

Example: 

Let's see an example.I am taking example of protection proxy. In our example, we have a folder in which you can perform various operation such as copy,paste file or subfolder.In OOP terms,we have IFolder interface and Folder class which provides performOperatons() method, and these are the existing class and interface that we cannot change. We want to further specify that only user with authorization can access it and perform operations such as cut or copy files and sub folder.

UML diagram for example:

Comparing with above generic elements,we have
  • FolderProxy(Proxy)
  • Folder(RealSubject)
  • IFolder(Subject)
Java codes for above classes:

IFolder.java (Subject):
package org.arpit.javapostsforlearning.designpatterns;

public interface IFolder {

    public void performOperations();
}
Following class is our realSubject class.Lets say we can not change it but we want to provide authorization on it.
Folder.java (RealSubject):
package org.arpit.javapostsforlearning.designpatterns;

public class Folder implements IFolder{

public void performOperations()
{
// access folder and perform various operations like copy or cut files
System.out.println("Performing operation on folder");
}

}
Following class provides authorization to Folder class.It checks for userName and password and if matched then only it gives access to folder.
FolderProxy.java(Proxy):
package org.arpit.javapostsforlearning.designpatterns;

public class FolderProxy implements IFolder{

Folder folder;
User user;

public FolderProxy(User user) {
this.user = user;
}


public void performOperations() {

if(user.getUserName().equalsIgnoreCase("arpit") && user.getPassword().equalsIgnoreCase("arpit"))
{
folder=new Folder();
folder.performOperations();
}
else
{
System.out.println("You don't have access to this folder");
}
}
}
User.java:
package org.arpit.javapostsforlearning.designpatterns;

public class User {

String userName;
String password;

public User(String userName, String password) {
this.userName = userName;
this.password = password;
}

public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}

}
ProxyDesignPatternMain.java:
package org.arpit.javapostsforlearning.designpatterns;

public class ProxyDesignPatternMain {

public static void main(String[] args) {

//When you click on folder,Lets say a GUI form will ask for userName and password.
//and this GUI will create this user object

// If we give correct userName and password
User user=new User("arpit","arpit");
FolderProxy folderProxy=new FolderProxy(user);
System.out.println("When userName and password are correct:");
folderProxy.performOperations();
System.out.println("**************************************");
// if we give wrong userName and Password
User userWrong=new User("abc","abc");
FolderProxy folderProxyWrong=new FolderProxy(userWrong);
System.out.println("When userName and password are incorrect:");
folderProxyWrong.performOperations();
}

}
Output:
When userName and password are correct:
Performing operation on folder
**************************************
When userName and password are incorrect:
You don't have access to this folder

So without changing Folder class,we have provide authentication to folder with the help of FolderProxy class.

Source code:

Source:Download 

Wednesday, September 19, 2012

Composite design pattern in java

Composite design patten allows you to have a tree structure and ask each node in the tree structure to perform a task.You can take real life example of a organization.It have general managers and under general managers, there can be managers and  under managers there can be developers.Now you can set a tree structure and ask each node to perform common operation like getSalary().

As described by Gof:
"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 means it has no objects below it.

Tree structure:


When to use it:

  • you want to represent part-whole hierachies of objects.
  • you want client to be able to ignore difference between compositions of objects and individual objects.Clients will treat all objects in the composite structure uniformly.

UML Diagram for Composite design pattern:

    Elements:

    • Component
      • declares interface for objects in composition.
      • implements deafault behaviour 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 behaviour for primitive objects in the composition.
    • Composite
      • defines behaviour 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.

    WorkFlow:

    Client use the component class interface to interact with objects in the composition structure.if recipient is a leaf then request is handled directly.If recipient is a composite,then it usually forwards request to its child components,possibly performing additional operations before and after forwarding.

    Recursion:

    What makes the Composite pattern one of the most beautiful is the power of recursion. I can explain this with the same organization example. You want to find the total salary paid to all employees of the organization. It is nothing but the salary of CEO + the salary paid to all the departments. What is the salary of a department? It is the salary of the department head + the salary of all projects. What is the total salary of a project? It is the salary of the project manager + the salary of all the project members. In short, the salary of anything is the salary of self + the salary of all its sub groups.

    Example:

    In a small organization,there are 5 employees.At top position,there is 1 general manager.Under general manager,there are two employees,one is manager and other is developer and further manager has two developers working under him.We want to print name and salary of all employees from top to bottom.

    Tree structure for example:

    UML diagram for above example:


    Comparing from above generic elements.Our example consist of following elements.
    • Manager(Composite)
    • Developer(Leaf)
    • Employee(Component)

    Java code for all above classes:

    First we will create component inrteface.It represents object in composition .It has all common operation that will be applicable to both manager and developer.
    Employee.java(Component) :

    package org.arpit.javapostsforlearning.designpatterns;

    public interface Employee {

         public void add(Employee employee);
         public void remove(Employee employee);
         public Employee getChild(int i);
         public String getName();
         public double getSalary();
         public void print();
    }
    Now we will create manager(composite class).Key point here is that all common method delegates its operations to child objects.It has method to access and modify its children.
    Manager.java(Composite):

    package org.arpit.javapostsforlearning.designpatterns;

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

    public 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 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);
    }

    }

    We will create developer class.This class is leaf node so all operations related to accessing children will be empty as it has no children.
    Developer.java(Leaf):
    package org.arpit.javapostsforlearning.designpatterns;
    /**
     * In this class,there are many methods which are not applicable to developer because
     * it is a leaf node.
     */

    public 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 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.
        }

    }

    CompositeDesignPatternMain.java:
    package org.arpit.javapostsforlearning.designpatterns;

    public class CompositeDesignPatternMain {

    public static void main(String[] args) {
    Employee emp1=new Developer("John", 10000);
    Employee emp2=new Developer("David", 15000);
    Employee manager1=new Manager("Daniel",25000);
    manager1.add(emp1);
    manager1.add(emp2);
    Employee emp3=new Developer("Michael", 20000);
    Manager generalManager=new Manager("Mark", 50000);
    generalManager.add(emp3);
    generalManager.add(manager1);
    generalManager.print();
    }
    }

    Output:
    -------------
    Name =Mark
    Salary =50000.0
    -------------
    -------------
    Name =Michael
    Salary =20000.0
    -------------
    -------------
    Name =Daniel
    Salary =25000.0
    -------------
    -------------
    Name =John
    Salary =10000.0
    -------------
    -------------
    Name =David
    Salary =15000.0
    -------------

    Disadvantages:

    • Once tree structure is defined,comosite design makes tree overly general.
    • Leaf class have to create some methods which has to empty.

    Usage in JDK:

    • java.util.Map#putAll(Map)
    • java.util.List#addAll(Collection)
    • java.util.Set#addAll(Collection)
    • java.nio.ByteBuffer#put(ByteBuffer) (also on CharBuffer, ShortBuffer, IntBuffer, LongBuffer, FloatBuffer and DoubleBuffer)
    • java.awt.Container#add(Component) 

    Adapter design pattern in java

    Real life example:

    A very simple example is using phone charger. Suppose your mobile phone needs 9 Volts of supply to get charged but main supply is 220 V which is not what you require but it can be a source and you can have something that can get 9 V out of this 220 V and supply to your phone for charging.
    Now phone charger is acting as an adapter for you.  So Basically it is making a relationship between two unrelated interfaces. This  is how Adpater pattern works.

    Intent:

    As described by Gof:
    "Convert the interface of class into another interface clients expect.Adapter lets class work together that couldn't otherwise because of incompatible interfaces".

    Also known as:

    Wrapper

    UML diagram of generic adapter design pattern:

    Elements:

    • Target
      • defines domains-specific interface client uses.
    • Client
      • collaborates with objects conforming to target interface.
    • Adaptee
      • defines existing interface that needs adapting
    • Adapter 
      • adapts the interface of adaptee to target interface. 

    WorkFlow:

    Clients call operations on the adapter instance.In turn adapter calls adaptee operations that carry out the request.

    When to use it:

    • You want to use existing class and its interface does not match the one you need.
    • You want to create a resuable class that cooperates with unrelated or unforeseen classes that is, class that don't necessarily have compatible interfaces.

    Example:

    UML Diagram for example:
    Comparing to above generic description of adapter pattern.
    My example includes following elements:
    • PrintableList(Target)
    • PrintString(Adaptee)
    • PrintableListAdapter(Adapter)

    Java code for all above classes:

    Consider that we have a third party library that provides print string functionality through PrintString class.
    This is our Adaptee. I know this is silly assumpsion but lets go with it for now.

    PrintString.java(Adaptee) :
    package org.arpit.javapostsforlearning.designpatterns;

    public class PrintString {

    public void print(String s)
    {
    System.out.println(s);
    }
    }

    Client deals with ArrayList<String> but not with string.We have provided a PrintableList interface that expects the client input.This is our target.

    PrintableList.java(Target):
    package org.arpit.javapostsforlearning.designpatterns;

    import java.util.ArrayList;

    public interface PrintableList {
    void printList(ArrayList<String> list);
    }
    Lets assume we can not change it now.
    Finally we have PrintableListAdapter class which will implement PrintableList interface and will deal with our adaptee class.
    PrintableListAdapter.java(Adapter):
    package org.arpit.javapostsforlearning.designpatterns;

    import java.util.ArrayList;

    public class PrintableListAdapter implements PrintableList{

    public void printList(ArrayList<String> list) {

    //Converting ArrayList<String> to String so that we can pass String to
    // adaptee class
    String listString = "";

    for (String s : list)
    {
    listString += s + "\t";
    }

    // instantiating adaptee class
    PrintString printString=new PrintString();
    ps.print(listString);
    }
    }

    AdapterDesignPatternMain.java:
    package org.arpit.javapostsforlearning.designpatterns;

    import java.util.ArrayList;
    public class AdapterDesignPatternMain {

    public static void main(String[] args)
    {
    ArrayList<String> list=new ArrayList<String>();
    list.add("one");
    list.add("two");
    list.add("three");
    PrintableList pl=new PrintableListAdapter();
    pl.printList(list);

    }
    }

    Output:

    one two three

    Bridge design pattern in java

    As stated by Gof:
    "Decouple an abstraction from its implementation so that the two can vary independently".

    When there are inheritance hierarchies in both interface and implementation then you loose coupling because of interdependence.In other words,Decoupling interface from implementation and hiding implementation detail of abstraction from client is main objectives of bridge design pattern.

    Also known as:

    Handle/Body

    UML diagram of generic bridge design pattern:

    Elements:

    • Abstraction
      • defines the abstraction' s interface.
      • maintain reference to object of type implementor.
    • RefinedAbstraction
      • extends the interface defined by abstraction.
    • Implementor
      • defines the interface for implementation classes.This interface doesn't have to correspond exactly to abstraction's interface;in fact the two interfaces can be quite different.Typically the implementor interface provides only primitive operations,and abstraction defines higher-level operations based on these primitives.
    • ConcreteImplementor
      • implements the implementor interface and defines its concrete implementation.

    When to use it:

    • Abstraction and implementation should be bound at compile time.
    • Both abstraction and implementation can have different hierarchies independently.You want to extend both hierarchies by subclassing.
    • Changes in implementation should have no impact on abstraction.
    • If you want to hide implementation of abstraction from client.
    • Best use when you have multiple implementation.

    WorkFlow:

    Abstaction forwards client request to its implementor object.

    Example:

    Before Applying bridge design pattern:

    After applying bridge design pattern:

    UML diagram for example:


    Comparing to above generic description of bridge pattern.
    My example includes following elements:
    • Shape(Abstraction)
    • Rectangle(RefinedAbstraction)
    • Circle(RefinedAbstraction)
    • Color(Implementor)
    • RedColor(ConcreteImplementor)
    • BlueColor(ConcreteImplementor)

     Java code for all above classes:

    We have two inheritance hierarchies here.i.e Shape and Color.Now with help of bridge design pattern both can vary independently.

    This is our abstraction class.
     Shape.java(Abstraction):

    package org.arpit.javapostsforlearning.designpatterns;

    abstract class Shape {
       
        Color color;
        Shape(Color color)
        {
            this.color=color;
        }
        abstract public void colorIt();
    }

    Rectangle.java(RefinedAbstraction):

    package org.arpit.javapostsforlearning.designpatterns;

    public class Rectangle extends Shape{

    Rectangle(Color color) {
    super(color);
    }

    public void colorIt() {
    System.out.print("Rectangle filled with ");
    color.fillColor();
    }
    }

    Circle.java(RefinedAbstraction):

    package org.arpit.javapostsforlearning.designpatterns;

    public class Circle extends Shape{

    Circle(Color color) {
    super(color);
    }

    public void colorIt() {
    System.out.print("Circle filled with ");
    color.fillColor();
    }
    }

    This is our implementor class.
    Color.java(Implementor):

    package org.arpit.javapostsforlearning.designpatterns;

    public interface Color {

    public void fillColor();
    }
    RedColor.java(ConcreteImplementor):
    package org.arpit.javapostsforlearning.designpatterns;

    public class RedColor implements Color{

    public void fillColor() {
    System.out.println("red color");
    }
    }
    BlueColor.java(ConcreteImplementor):
    package org.arpit.javapostsforlearning.designpatterns;

    public class BlueColor implements Color{

    public void fillColor() {
    System.out.println("blue color");
    }
    }
    BridgeDesignPatternMain.java:
    package org.arpit.javapostsforlearning.designpatterns;

    public class BridgeDesignPatternMain {

    public static void main(String[] args) {

    Shape s1=new Rectangle(new RedColor());
    s1.colorIt();
    Shape s2=new Circle(new BlueColor());
    s2.colorIt();
    }
    }

     Output:

    Rectangle filled with red color
    Circle filled with blue color

    Related patterns:

    An Abstract Factory can create and configure a particular bridge.

    The Adapter design pattern convert interface of a class ito another interface clients expects.It is usually applied to system after they are designed.Bridge on other hand is used up-front in a design to let abstractions and implementation vary independently.

    Thursday, July 12, 2012

    Decorator Design Pattern

    The Decorator design pattern attach additional responsibilities to an object dynamically.It is wrap up at another object.It will extend functionality of object without affecting any other object.Decorators provide a alternative to subclassing for extending functionality.

    Also known as:

    Wrapper

    When to use it:

    Use Decoraotor
    • to add responsibilities to individual objects dynamically without affecting other objects.
    • for responsibilities that can be withdrawn,
    • When extension by subclassing is impractical.Sometimes a large number of independent extensions are possible and would produce an explosion of subclasses to support every combination.Or class definition may be hidden or otherwise unavailable for subclassing.

    UML diagram for decorator design pattern:

    Elements:

    • Component
      • defines interface for objects that can have additional responsibilities added to them.
    • ConcreteComponent
      • defines an object on which additional responsibilities  can be added
    • Decorator
      • maintains a reference to component object and defines an interface that conforms to component's interface.In simple words,It has a component object to be decorated.
    • ConcreteDecorator
      • add responsibilities to the component object.

    Example:

    In this example,we will decorate a simple room with color and curtains. 
    • Room(Component)
      • It is an interface which creates a blue print for the class which will have decorators
    • SimpleRoom(ConcreteComponent)
      • Object of SimpleRoom class will be decorated.Additional responsibilities will be attached to it dynamically.
    • RoomDecorator(Decorator)
      • It contains reference to Room class which will be decorated.
    •  ColorDecorator(ConcreteDecorator)
      • ColorDecorator will add additional responsibility i.e.add color to room.
    • CurtainDecorator(ConcreteDecorator)
      • CurtainDecorator will add  additional responsibility i.e. add curtains to room.
    Logically,you can think of decorator pattern as shown in above diagram.You will first created SimpleRoom object then decorate it with ColorDecorator object and then decorate resultant object with CuratainDecorator.

    Java code for above classes:

    The following interface is an interface depicting an room.
    Room.java(Component):
    package org.arpit.javapostsforlearning.designPattern;

    public interface Room{
    public String showRoom();
    }
     Following class is a concrete implementation of this interface. This is the base class on which the decorators will be added.
    SimpleRoom.java(ConcreteComponent) :
    package org.arpit.javapostsforlearning.designPattern;

    public class SimpleRoom implements Room {

    @Override
    public String showRoom() {
    return "Normal Room";
    }

    }
    Following class is the decorator class. It is the core of the decorator design pattern. It contains an attribute for the type of interface. Instance is assigned dynamically at the creation of decorator using its constructor. Once assigned that instance method will be invoked.
    RoomDecorator.java(Decorator):
    package org.arpit.javapostsforlearning.designpattern;

    abstract class RoomDecorator implements Room{

    protected Room specialRoom;

    public RoomDecorator (Room specialRoom) {
    this.specialRoom= specialRoom;
    }

    public String showRoom() {
    return specialRoom.showRoom();
    }
    }
    Following class is our concrete decorator class.It extends abstract decorator.When this decorator is created,base instance is passed to constructor which calls super class constructor.In showRoom() method, we call base class method followed by its own method addColors.This addColors() adds functionality to base instance i.e. decorating  room with colors.
    ColorDecorator.java(ConcreteDecorator):
    package org.arpit.javapostsforlearning.designpattern;

    public class ColorDecorator extends RoomDecorator {

    public ColorDecorator (Room specialRoom) {
    super(specialRoom);
    }

    public String showRoom() {
    return specialRoom.showRoom() + addColors();
    }

    private String addColors() {
    return " + Blue Color";
    }
    }
    Following class is also concreteDecorator class similar to above class.here addCurtains() add functionality to room(base instance) i.e. decorating room with curtains.
    CurtainDecorator.java(ConcreteDecorator):
    package org.arpit.javapostsforlearning.designPattern;

    public class CurtainDecorator extends RoomDecorator {

    public CurtainDecorator (Room specialRoom) {
    super(specialRoom);
    }

    public String showRoom() {
    return specialRoom.showRoom() + addCurtains();
    }

    private String addCurtains() {
    return " + Red Curtains";
    }
    }
    DecoratorDesignPatternMain.java:
    package org.arpit.javapostsforlearning.designpattern;  
    public class DecoratorDesignPatternMain {

    public static void main(String args[]) {
    Room room = new CurtainDecorator(new ColorDecorator(new SimpleRoom()));
    System.out.println(room.showRoom());
    }

    }
    I have created a simple Room and decorated that with color and curtains.

    Output:
    Normal room + Blue Color + Red Curtains

    Advantages of decorator design pattern: 

    • It is flexible than inheritance because inheritance adds responsibility at compile time but decorator pattern adds at run time.
    • We can have any number of decorators and also in any order.
    • It extends functionality of object without affecting any other object.

    Disadvantage of decorator design pattern:

    Main disadvantage of decorator design pattern is code maintainability because this pattern creates lots of similar decorator which are sometimes hard to maintain and distinguish.

    Decorator Design Pattern in java API:

    java.io.BufferedReader;
    java.io.BufferedWriter;
    java.io.FileReader;
    java.io.Reader;
    The above classes of java API are designed using decorator design pattern.

    Source code:

    Source:Download