Decorator Pattern

Decorator Pattern

A Decorator Pattern says that just "attach a flexible additional responsibilities to an object dynamically".
In other words, The Decorator Pattern uses composition instead of inheritance to extend the functionality of an object at run-time. Decorator pattern allows a user to add new functionality to an existing object without altering its structure.
.
The Decorator Pattern is also known as Wrapper.

Advantage of Decorator Pattern

  • It provides greater flexibility than static inheritance.
  • It enhances the extensibility of the object, because changes are made by coding new classes.
  • It simplifies the coding by allowing you to develop a series of functionality from targeted classes instead of coding all of the behaviour into the object.
  • The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime.
  • 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.
  • Decorator offers a pay-as-you-go approach to adding responsibilities. Instead of trying to support all foreseeable features in a complex, customizable class, you can define a simple class and add functionality incrementally with Decorator objects.

Disadvantage of Decorator Pattern

  • Decorators can complicate the process of instantiating the component because you not only have to instantiate the component, but wrap it in a number of decorators.
  • It can be complicated to have decorators keep track of other decorators, because to look back into multiple layers of the decorator chain starts to push the decorator pattern beyond its true intent.

Usage of Decorator Pattern

It is used:

  • When you want to transparently and dynamically add responsibilities to objects without affecting other objects.
  • When you want to add responsibilities to an object that you may want to change in future.
  • Extending functionality by sub-classing is no longer practical.

Implementation

We're going to create a Shape interface and concrete classes implementing the Shapeinterface. We will then create an abstract decorator class ShapeDecorator implementing the Shape interface and having Shape object as its instance variable.
RedShapeDecorator is concrete class implementing ShapeDecorator.
DecoratorPatternDemo, our demo class will use RedShapeDecorator to decorate Shapeobjects.
Decorator Pattern UML Diagram

Step 1

Create an interface.
Shape.java
public interface Shape {
   void draw();
}

Step 2

Create concrete classes implementing the same interface.
Rectangle.java
public class Rectangle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Rectangle");
   }
}
Circle.java
public class Circle implements Shape {

   @Override
   public void draw() {
      System.out.println("Shape: Circle");
   }
}

Step 3

Create abstract decorator class implementing the Shape interface.
ShapeDecorator.java
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;

   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }

   public void draw(){
      decoratedShape.draw();
   }	
}

Step 4

Create concrete decorator class extending the ShapeDecorator class.
RedShapeDecorator.java
public class RedShapeDecorator extends ShapeDecorator {

   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);		
   }

   @Override
   public void draw() {
      decoratedShape.draw();	       
      setRedBorder(decoratedShape);
   }

   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color: Red");
   }
}

Step 5

Use the RedShapeDecorator to decorate Shape objects.
DecoratorPatternDemo.java
public class DecoratorPatternDemo {
   public static void main(String[] args) {

      Shape circle = new Circle();

      Shape redCircle = new RedShapeDecorator(new Circle());

      Shape redRectangle = new RedShapeDecorator(new Rectangle());
      System.out.println("Circle with normal border");
      circle.draw();

      System.out.println("\nCircle of red border");
      redCircle.draw();

      System.out.println("\nRectangle of red border");
      redRectangle.draw();
   }
}

Step 6

Verify the output.
Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

Comments

Popular posts from this blog

gsutil Vs Storage Transfer Service Vs Transfer Appliance

SQL basic interview question