Friday, 13 April 2012

Decorator Design Pattern with an Example

Definition:
               Attach additional responsibilities or functions to an object dynamically or statically. Also known as Wrapper.

Where to use & benefits:
  1. Provide an alternative to subclassing.
  2. Add new function to an object without affecting other objects.
  3. Make a responsibility easily added and removed dynamically.
  4. More flexibility than static inheritance.
  5. Transparent to the object.
  6. Related patterns include  
  •  Adapter pattern, which provides a different interface to the object it adapts, whereas a decorator changes an object's responsibilities,
  • Proxy pattern, which controls access to the object, whereas a decorator focuses on adding new functions to an object,
  • Composite pattern, which aggregates an object, whereas a decorator adds additional responsibilities to an object, and
  • Strategy pattern, which changes the guts of an object, whereas a decorator changes the skin of an object.
  • Facade pattern, which provides a way of hiding a complex class, whereas a decorator adds function by wrapping a class. 
Example on DecoratorDesignPattern :

A JScrollPane object can be used to decorate a JTextArea object or a JEditorPane object. A window can be decorated with different borders like BevelBorder, CompoundBorder, EtchedBorder TitledBorder etc. These border classes working as decorators are provided in Java API.

Design Patterns in Java(TM) can be used in a non-visual fashion. For example, BufferedInputStream, DataInputStream, and CheckedInputStream are decorating objects of FilterInputStream class. These decorators are standard Java API classes.

To illustrate a simple decorator pattern in non-visual manner, we design a class that prints a number. We create a decorator class that adds a text to the Number object to indicate that such number is a random number. Of course we can subclass the Number class to achieve the same goal. But the decorator pattern provides us an alternative way. 



import java.util.Random;
class Number {
   public void print() {
       System.out.println(new Random().nextInt());
   }
}
 
class Decorator {
    public Decorator() {
        System.out.print("Random number: ");//add a description to the number printed
        new Number().print();
    }
}
 
class SubNumber extends Number{
    public SubNumber() {
       super();
       System.out.print("Random number: ");
       print();
    }
}
 
class Test {
    public static void main(String[] args) {
        new Decorator();
        new SubNumber();
    }
}

The Output of the above program:

java Test
Random number: 145265744
Random number: 145265755

Factory Design Pattern with a real time Example

The Factory design pattern comes under Creational design pattern.

Definition

Provides an abstraction or an interface and lets subclass or implementing classes decide which class or method should be instantiated or called, based on the conditions or parameters given.

Where to use & benefits
  1. Connect parallel class hierarchies.
  2. A class wants its subclasses to specify the object.
  3. A class cannot anticipate its subclasses, which must be created.
  4. A family of objects needs to be separated by using shared interface.
  5. The code needs to deal with interface, not implemented classes.
  6. Hide concrete classes from the client.
  7. Factory methods can be parameterized.
  8. The returned object may be either abstract or concrete object.
  9. Providing hooks for subclasses is more flexible than creating objects directly.
  10. Follow naming conventions to help other developers to recognize the code structure.
    Related patterns include
    • Abstract Factory , which is a layer higher than a factory method.
    • Template method, which defines a skeleton of an algorithm to defer some steps to subclasses or avoid subclasses.
    • Prototype, which creates a new object by copying an instance, so it reduces subclasses.
    • Singleton, which makes a returned factory method unique.
Here is a popular example of Factory design pattern.

To illustrate how to use factory design pattern with class level implementation, here is a real world example. A company has a website to display testing result from a plain text file. Recently, the company purchased a new machine which produces a binary data file, another new machine on the way, it is possible that one will produce different data file. How to write a system to deal with such change. The website just needs data to display. Your job is to provide the specified data format for the website.  

Here comes a solution. Use an interface type to converge the different data file format. The following is a skeleton of implementation.

//Let's say the interface is Display
interface Display {
 
   //load a file
   public void load(String fileName);
 
   //parse the file and make a consistent data type
   public void formatConsistency();
 
}
 
//deal with plain text file
class CSVFile implements Display{
 
    public void load(String textfile) {
        System.out.println("load from a txt file");
    }
    public void formatConsistency() {
        System.out.println("txt file format changed");
    } 
}
 
//deal with XML format file
class XMLFile implements Display {
 
    public void load(String xmlfile) {
        System.out.println("load from an xml file");
    }
    public void formatConsistency() {
        System.out.println("xml file format changed");
    } 
}
 
//deal with binary format file
class DBFile implements Display {
 
    public  void load(String dbfile) {
        System.out.println("load from a db file");
    }
    public void formatConsistency() {
        System.out.println("db file format changed");
    } 
}



Test the functionality of above methods with a main program.



class TestFactory {
    public static void main(String[] args) {
        Display display = null;
         
        //use a command line data as a trigger
        if (args[0].equals("1"))
           display = new CSVFile();
        else if (args[0].equals("2"))
           display = new XMLFile();
        else if (args[0].equals("3"))
           display = new DBFile();
        else
           System.exit(1);
        //converging code follows
        display.load("");
        display.formatConsistency();
   }   
}


//after compilation and run it



C:\>java TestFactory 1
load from a txt file
txt file format changed
C:\>java TestFactory 2
load from an xml file
xml file format changed
C:\>java TestFactory 3
load from a db file
db file format changed
Related Posts Plugin for WordPress, Blogger...