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
Ensure a class has only one instance, and provide a global point of access to it.
This method has a number of advantages:
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; } }
- The instance is not constructed until the class is used.
- There is no need to
synchronize
thegetInstance()
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. |
No comments:
Post a Comment