Thursday 18 July 2013

Few Important Design Patterns

Few Important Design Patterns

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design.

Creational Design Patterns

1. Abstract factory :

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

Example

interface Button is
  method paint()

interface GUIFactory is
  method createButton()
      output:  a button

class WinFactory implementing GUIFactory is
  method createButton() is
      output:  an Windows button
    Return a new WinButton

class OSXFactory implementing GUIFactory is
  method createButton() is
      output:  an OS X button
    Return a new OSXButton

class WinButton implementing Button is
  method paint() is
    Render a button in a Windows style

class OSXButton implementing Button is
  method paint() is
    Render a button in a Mac OS X style

class Application is
  constructor Application(factory) is
      input:  the GUIFactory factory used to create buttons
    Button button := factory.createButton()
    button.paint()

Read the configuration file
If the OS specified in the configuration file is Windows, then
  Construct a WinFactory
  Construct an Application with WinFactory
else
  Construct a OSXFactory
  Construct an Application with OSXFactory
 
 
2. Factory method
 
Define an interface for creating a single object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses

The benefit is that the client code (calling code) can just say "give me an object that can do XYZ" without knowing what is the actual class that can do "XYZ".

3. Singleton

Ensure a class has only one instance, and provide a global point of access to it.

Lazy initialization
This method uses double-checked locking, which should not be used prior to J2SE 5.0, as it is vulnerable to subtle bugs. The problem is that an out-of-order write may allow the instance reference to be returned before the Singleton constructor is executed.[9]
public class SingletonDemo {
        private static volatile SingletonDemo instance = null;
 
        private SingletonDemo() {       }
 
        public static SingletonDemo getInstance() {
                if (instance == null) {
                        synchronized (SingletonDemo .class){
                                if (instance == null) {
                                        instance = new SingletonDemo ();
                                }
                      }
                }
                return instance;
        }
}
Eager initialization
If the program will always need an instance, or if the cost of creating the instance is not too large in terms of time/resources, the programmer can switch to eager initialization, which always creates an instance:
public class Singleton {
    private static final Singleton instance = new Singleton();
 
    private Singleton() {}
 
    public static Singleton getInstance() {
        return instance;
    }
}
This method has a number of advantages:
  • The instance is not constructed until the class is used.
  • There is no need to synchronize the getInstance() method, meaning all threads will see the same instance and no (expensive) locking is required.
  • The final keyword means that the instance cannot be redefined, ensuring that one (and only one) instance ever exists.
Static block initialization
Some authors[10] refer to a similar solution allowing some pre-processing (e.g. for error-checking). In this sense, the traditional approach could be seen as a particular case of this one, as the class loader would do exactly the same processing.
public class Singleton {
  private static final Singleton instance;
 
  static {
    try {
      instance = new Singleton();
    } catch (IOException e) {
      throw new RuntimeException("Darn, an error occurred!", e);
    }
  }
 
  public static Singleton getInstance() {
    return instance;
  }
 
  private Singleton() {
    // ...
  }
} 
 
The solution of Bill Pugh
 The technique known as the initialization on demand holder idiom, is as lazy as possible, and works in all known versions of Java. It takes advantage of language guarantees about class initialization, and will therefore work correctly in all Java-compliant compilers and virtual machines. The nested class is referenced no earlier (and therefore loaded no earlier by the class loader) than the moment that getInstance() is called. Thus, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized).

public class Singleton {
        // Private constructor prevents instantiation from other classes
        private Singleton() { }
 
     /**
     * SingletonHolder is loaded on the first execution of Singleton.getInstance() 
     * or the first access to SingletonHolder.INSTANCE, not before.
     */
        private static class SingletonHolder { 
                public static final Singleton INSTANCE = new Singleton();
        }
 
        public static Singleton getInstance() {
                return SingletonHolder.INSTANCE;
        }
} 
 
Behavioural Design Pattern

1. Adapter / Wrapper / Translator Patter
 
 It translates one interface for a class into a compatible interface.
 An adapter helps two incompatible interfaces to work together. 
Implementation of Adapter pattern
When implementing the adapter pattern, for clarity use the class name [AdapteeClassName]To[Interface]Adapter, for example DAOToProviderAdapter. It should have a constructor method with adaptee class variable as parameter. This parameter will be passed to the instance member of [AdapteeClassName]To[Interface]Adapter.
public class AdapteeToClientAdapter implements Client {
 
    private final Adaptee instance;
 
    public AdapteeToClientAdapter(final Adaptee instance) {
         this.instance = instance;
    }
 
    @Override
    public void clientMethod() {
       // call Adaptee's method(s) to implement Client's clientMethod
    }
 
} 
 
2. Decorator pattern
 
Decorator design pattern is used to enhance the functionality of a particular object at run-time or 
dynamically.

JDK use decorator pattern in IO package where it has decorated Reader and Writer Classes for various 
scenario, for example BufferedReader and BufferedWriter are example of decorator design pattern in 
Java.
 
3.  Facade


Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use.
 
Example
This is an abstract example of how a client ("you") interacts with a facade (the "computer") to a complex system (internal computer parts, like CPU and HardDrive).

/* Complex parts */
 
class CPU {
    public void freeze() { ... }
    public void jump(long position) { ... }
    public void execute() { ... }
}
 
class Memory {
    public void load(long position, byte[] data) { ... }
}
 
class HardDrive {
    public byte[] read(long lba, int size) { ... }
}
 
/* Facade */
 
class Computer {
    private CPU processor;
    private Memory ram;
    private HardDrive hd;
 
    public Computer() {
        this.processor = new CPU();
        this.ram = new Memory();
        this.hd = new HardDrive();
    }
 
    public void start() {
        processor.freeze();
        ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
        processor.jump(BOOT_ADDRESS);
        processor.execute();
    }
}
 
/* Client */
 
class You {
    public static void main(String[] args) {
        Computer facade = new Computer();
        facade.start();
    }
} 
 
4. Front Controller

The pattern relates to the design of Web applications. It provides a centralized entry point for handling requests.
 
Example : Struts 2 framework





  

No comments:

Post a Comment