Tuesday, 1 October 2013

Decorator Pattern


The Decorator all about extending the functionality of a given class. After you’ve written a class, you can add decorators (additional classes) to extend that class; doing so means that you won’t have to keep modifying the original class’s code over and over again.

This is the perfect example of 'O' in SOLID design principle

Closed for Modification, Open for Extension

In your house warming ceremony you decided to decorate your house . The contractor has following rates.

Basic decoration –2000 Rs
Flower Decoration – Basic decoration + 2000
Baloon Decoration – Basic decoration + 1000
Light Decoration – Basic decoration + 3000

public class BasicDecoration {

      public String description() {
            return "basic Decoration";
      }

}
When a new BasicDecoration object is created, its description method returns the text  basic Decoration . So far, so good. But some customers decide that they want a Flower Decoration . “No problem,” the company programmers say. “We can just change the code this way”:

public class BasicDecoration {

      public String description() {
            return "basic Decoration + Flower Decoration ";
      }
     

}
But some customers are never satisfied — they want a lighhning  too. So the
company programmers change the code again to this:

public class BasicDecoration {

      public String description() {
            return "basic Decoration + Flower Decoration +light";
      }
           

}
You can see the issue here: The company programmers have to change the code every time someone wants to customize his or her purchase. Obviously, that’s a problem.

Closed for Modification, Open for Extension


public class BasicDecoration {

      public BasicDecoration() {
      }

      public String description() {
            return "basic Decoration";
      }
     
      public int rate() {
            return 2000;
      }
     

}


class LightDecoration extends BasicDecoration {

      BasicDecoration basicDecoration;

      public LightDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + LightDecoration";
      }

     
      public int rate() {
            return basicDecoration.rate()+3000;
      }
}





class FlowerDecoration extends BasicDecoration {

      BasicDecoration basicDecoration;

      public FlowerDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + FlowerDecoration";
      }

      public int rate() {
            return basicDecoration.rate()+2000;
      }
     
}




class BaloonDecoration extends BasicDecoration {

      public BaloonDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      BasicDecoration basicDecoration;

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + BaloonDecoration";
      }

     
      public int rate() {
            return basicDecoration.rate()+1000;
      }
     
}

Since we have to put basic decoration at the core and then add extra accessories . That’s way new BasicDecoration()inside the root. (bottom of the heart)

class BasicDecorationTest {

      public static void main(String[] args) {

            BasicDecoration basicDecoration = new FlowerDecoration(
                        new LightDecoration(new BaloonDecoration(new BasicDecoration())));

            System.out.println(basicDecoration.description());

      }

}

Here in this code all the classes extends BasicDecoration . In order to compel all the classes to override  description() and rate()


abstract class ComponentDecorator extends BasicDecoration {
      public abstract String description();
      public abstract int rate();
}

We write a abstract class ComponentDecorator that extends BasicDecoration and remaining class will extend this abstract class . In this way the contract is established. No chances of errors


class LightDecoration extends ComponentDecorator {

      BasicDecoration basicDecoration;

      public LightDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + LightDecoration";
      }

     
      public int rate() {
            return basicDecoration.rate()+3000;
      }
}


class FlowerDecoration extends ComponentDecorator {

      BasicDecoration basicDecoration;

      public FlowerDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + FlowerDecoration";
      }

      public int rate() {
            return basicDecoration.rate()+2000;
      }
     
}

class BaloonDecoration extends ComponentDecorator {

      public BaloonDecoration(BasicDecoration basicDecoration) {
            this.basicDecoration = basicDecoration;
      }

      BasicDecoration basicDecoration;

      @Override
      public String description() {
            // TODO Auto-generated method stub
            return basicDecoration.description() + " + BaloonDecoration";
      }

     
      public int rate() {
            return basicDecoration.rate()+1000;
      }
     
}


Second Example



class Gift {

      public int getValue() {
            return 1000;
      }

}

abstract class GiftWrapper extends Gift {

    public abstract int getValue();

}

class GiftBox extends GiftWrapper {

      private Gift gift;

      public GiftBox(Gift gift) {
            this.gift = gift;
      }

      public int getValue() {
            return  gift.getValue() +10;
      }

}

class GiftWrapPaper extends GiftWrapper {

      private Gift gift;

      public GiftWrapPaper(Gift gift) {
            this.gift = gift;
      }


      public int getValue() {
             return gift.getValue() +5;
      }

}

class Ribbon extends GiftWrapper {

      private Gift gift;

      public Ribbon(Gift gift) {
            this.gift = gift;
      }

      public int getValue() {
            return gift.getValue() + 2;
      }

}


public class TestGift {

      public static void main(String[] args) {
           
Gift gift = new Ribbon(new GiftWrapPaper(new GiftBox(new Gift())));
           
            System.out.println(gift.getValue());
           
      }

}

Real Example is as follows
public class Test {

      public static void main(String[] args) throws IOException {

            File file = new File("d:\\data\\a.txt");

            FileReader fr = new FileReader(file);

            BufferedReader br = new BufferedReader(fr);

            String str = br.readLine();
            while (str != null) {
                  System.out.println(str);
                  str = br.readLine();
            }

      }

java.io 
Class Reader

java.lang.Object
  extended by java.io.Reader
All Implemented Interfaces:
Direct Known Subclasses:

public class BufferedReader extends Reader




Class FileReader (Convenience class for reading character files.)

java.lang.Object
  extended by java.io.Reader
      extended by java.io.InputStreamReader
          extended by java.io.FileReader
All Implemented Interfaces:

public class FileReader extends InputStreamReader



java.io 
Class BufferedReader (Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.)

java.lang.Object
  extended by java.io.Reader
      extended by java.io.BufferedReader
All Implemented Interfaces:


public class BufferedReader extends Reader

No comments:

Post a Comment