Design patterns are solutions to general problems that software developers face during software development.
This says given a context, this is the best design and solution.
Design Patterns credit goes to Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (Gang of Four -GoF)
for coming out with a good collection of Patterns for common Design Problems.
As per GOF, the Design Patterns are catagorized in 3 parts: Creational, Structural and Behavioral.
Creational : Talk about Object creation.
Structural : Talk about Object and Class composition like inheritance and Association.
Behavioral : Talk about Dynamic Object interaction and distribution of responsibilities.
--------------------------------------------------------------
Creational:
Factory: Toy Factory uses Plastic(one super class) with different molds(several sub classes). Creates an instance of several derived classes.
Factory design pattern is used when do not want to give constructor of a class where object can be created using new keyword.
It means in Factory Pattern, you are not able to use "new keyword to create objects".
Calendar c = Calendar.getInstance();
Calendar c = Calendar.getInstance(TimeZone);
Calendar c = Calendar.getInstance(Locale);
Thread th = Thread.currentThread();
Class c = Class.forName();
Runtime rt = Runtime.getRuntime();
Abstract Factory Pattern: This is called Factory of Factories. This work around a super factory concept.
https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm
Builder: Separates the construction of a complex object from its representation. There will be overloaded constructors to create objects.
StringBuffer and StringBuilder.
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder(int capacity);
StringBuilder sb = new StringBuilder(String);
StringBuilder sb = new StringBuilder(String).append(String);
StringBuilder sb = new StringBuilder(String).append(double);
StringBuilder sb = new StringBuilder(String).insert(int, int);
Prototype: A fully initialized instance to be copied or cloned. java.lang.Object#clone() method creates java.lang.Object.
Again you shouldn't use new keyword to create object.
Singleton: President of a country, System class, SessionFactory etc. A class of which only a single instance should exist.
Config Property file reading/loading.
DB ConnectionPool object.
java.lang.Runtime#getRuntime().
http://deepakmodi2006.blogspot.in/2011/05/singleton-pattern-in-java.html
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SingletonPattern implements Cloneable, Serializable{
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
--------------------------------------------------------------
Structural:
Adapter: Adapter pattern works as a bridge between two incompatible interfaces. Also called Wrapper patterns.
Wrapper classes, Arrays.asList() gives List object. Adapter design pattern makes incompatible interfaces
work together, without changing them. Ex: you have 2 dimensional array and want an adapter to create a Map
and automatically load the array as key value pair.
public static void main(String args[]) {
Integer[][] squares = { {2, 4}, {3, 9}, {4, 16}};
MapAdapter adapter = new MapAdapter(squares);
System.out.println("Adapter map contains: " + adapter); //Adapter map contains: {2=4, 3=9, 4=16}
}
class MapAdapter extends AbstractMap {
private Map map;
public MapAdapter(Object[][] array) {
super();
map = new HashMap();
for(Object[] mapping : array){
map.put(mapping[0], mapping[1]);
}
}
@Override
public Set entrySet() {
return map.entrySet();
}
}
Bridge:
Composite:
Decorator: Decorator pattern allows a user to add new functionality to an existing object without altering its structure.
Example: https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm
Facade: Customer care (A single class that represents an entire subsystem). Facade pattern hides the complexities of the system
and provides an interface to the client using which the client can access the system.
Example: https://www.tutorialspoint.com/design_pattern/facade_pattern.htm
Flyweight:
Proxy: Check book leaf, Credit card, Debit card are proxy for Money. An object representing another object.
java.rmi.*, the whole API actually.
--------------------------------------------------------------
Behavioral:
Chain of Responsibility: Loan/Leave approval process. A way of passing a request between a chain of objects.
javax.servlet.Filter#doFilter()
Command: Command pattern is a data driven design pattern. A request is wrapped under an object as command and passed to
invoker object. Invoker object looks for the appropriate object which can handle this command and passes the
command to the corresponding object which executes the command.
https://www.tutorialspoint.com/design_pattern/command_pattern.htm
Iterator: Next/Previous buttons on TV. Sequentially access the elements of a collection.
All implementations of java.util.Iterator & java.util.Enumeration.
public interface Iterator {
public boolean hasNext();
public Object next();
}
for(Iterator iter = Map.keySet().iterator(); iter.hasNext(); ){
String name = (String)iter.next();
System.out.println("Name : " + name);
}
https://www.tutorialspoint.com/design_pattern/iterator_pattern.htm
Mediator:
Momento: Memento pattern is used to restore state of an object to the previous state.
Implementations of java.io.Serializable.
Observer: A way of notifying change to a number of classes. Publish/Subscribe JMS API. NotifyMe in e-commerce websites.
State:
Strategy: In Strategy pattern, we create objects which represent various strategies and a context object whose behavior
varies as per its strategy object. The strategy object changes the executing algorithm of the context object.
https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
Visitor:
============================END=====================
Showing posts with label Design Pattern. Show all posts
Showing posts with label Design Pattern. Show all posts
Saturday, March 3, 2012
Types of Design patterns in Java
Observer Design Pattern in Java
The Observer Pattern works on principle of "Notify Me" when State of Subject (called Observable) changes. This
is a one to many relationship between Subject and Observers/Listeners. The only clause is "Observers" can register-deregister
any time. The loose coupling must be maintained.
Example:
Customers clicking "Notify Me" button in fashion sites/mobile items when the item is "Out of Stock".
When the same item again becomes "In-Stock", all these customers/observers gets email/notified. Here item
is called subject/observable.
Stock Market Sites like Sharekhan, Zerodha, India Infoline (observers) updates stock activities like Prices, Traded volumns,
Orders whenever price change happens in Nifty.
ClusterNotification: If a card gets blocked or device is black listed, a notice should be issued (notify should be invoked) among
all the Servers so they can stop the blocked card transaction.
Rule change in White House (Donald Trump has signed the bill to stop citizens of 7 muslim countries) triggers notifications to all
the Observers (Airports, Visa Authorities who are registered with White House) to ban these 7 countries citizens.
Also called publish-subscribe pattern.
Whether forcasting display system which keeps getting updated from real time data (data comes from Physical machine sensors
like "Humidity censors, Temperature censors").
Things required to implement Observer Pattern:
1) One Observer interface, which will have update method.
2) One Observable/Subject/RuleSet, which will have register(), unregister(), notifyAll() methods.
3) One Subject Integrator where Subject/RuleSet methods are implemented, like NSE (National Stock Exchange: Sharekhan,
Zerodha need to register themselves first).
4,5) 2 Observers which will implement above interface (Sharekhan, Zerodha) for display their prices after update.
Note that the Sharekhan and Zerodha Observers must maintain a reference variable of type Subject for calling
register, unregister, notifyAll. Because of loose coupling, they can register-unregister independently.
6) Main Program to see all.
7) Total 6 Programs
=============Observer.java============
package designpattern.observerpattern;
public interface Observer {
public void update(int infySharePrice);
}
===============Subject.java, The RuleSet=============
package designpattern.observerpattern;
public interface Subject {
public void addObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
===============NSE.java, The integrator===============
package designpattern.observerpattern;
import java.util.ArrayList;
import java.util.List;
public class NSE implements Subject {
int infosysSharePrice = 1000;
public void setInfosysSharePrice(int v) {
infosysSharePrice = v;
}
List<Observer> observers = new ArrayList<Observer>(); //To maintain list of registered observers.
public void addObserver(Observer o){
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
for (int i=0; i<observers.size();i++) {
Observer ob = (Observer)observers.get(i);
ob.update(infosysSharePrice);
}
}
}
===============Sharekhan.java===============
package designpattern.observerpattern;
public class Sharekhan implements Observer { //This is an Observer
int latestValue = 0;
Subject nseRegistration;
public Sharekhan(NSE nse) {
nseRegistration = nse;
nseRegistration.addObserver(this);
}
public void update(int value) {
latestValue = value;
System.out.println("Sharekhan, Infosys Stock Price=" + latestValue);
}
public void unregister(){
nseRegistration.removeObserver(this);
}
}
===============Zerodha.java===============
package designpattern.observerpattern;
public class Zerodha implements Observer { //This is an Observer
int latestValue = 0;
Subject nseRegistration;
public Zerodha(NSE nse) {
nseRegistration = nse;
nseRegistration.addObserver(this);
}
public void update(int value) {
latestValue = value;
System.out.println("Zerodha, Infosys Stock Price=" + latestValue);
}
}
===============MainProgram.java===============
package designpattern.observerpattern;
public class MainProgram {
public static void main(String[] args) {
NSE stockExchangeIntegrator = new NSE();
Sharekhan obs1 = new Sharekhan(stockExchangeIntegrator); //Create Observer object, pass integrator
Observer obs2 = new Zerodha(stockExchangeIntegrator); //Create Observer object, pass integrator
System.out.println("Initial Price..............");
stockExchangeIntegrator.notifyObservers();
System.out.println("\nAfter few Days Price..............");
stockExchangeIntegrator.setInfosysSharePrice(1070);
stockExchangeIntegrator.notifyObservers();
System.out.println("\nAfter removing Sharekhan observer..............");
obs1.unregister(); //Sharekhan unregistered now
stockExchangeIntegrator.setInfosysSharePrice(1100);
stockExchangeIntegrator.notifyObservers();
}
}
//Output:
Initial Price..............
Sharekhan, Infosys Stock Price=1000
Zerodha, Infosys Stock Price=1000
After few Days Price..............
Sharekhan, Infosys Stock Price=1070
Zerodha, Infosys Stock Price=1070
After removing Sharekhan observer..............
Zerodha, Infosys Stock Price=1100
=========================================================
Wednesday, February 29, 2012
Factory Design Pattern
Factory Design Pattern is a creational pattern. This is required when you don't want to give constructor to
create object using new keyword.
Ex: Toy factory which makes different kind of toys: some in shape of aeroplane, some in shape of a racing car functions.
---------------------------------------
package deepak;
public interface Pet {
public String speak();
}
package deepak;
public class Cat implements Pet {
public String speak(){
return "Meau Meau";
}
}
package deepak;
public class Dog implements Pet {
public String speak(){
return "Bhow Bhow";
}
}
package deepak;
public class PetFactory {
public static Pet getPetInstance(String petType) {
Pet pet = null;
//Based on logical factory instantiates an object
if ("Bhow".equals(petType))
pet = new Dog();
else if ("Meau".equals(petType))
pet = new Cat();
return pet;
}
public static void main(String[] args) {
Pet object = PetFactory.getPetInstance("Bhow");
Pet object2 = PetFactory.getPetInstance("Meau");
System.out.println(object);
System.out.println(object2);
}
}
--------------Output:----------
deepak.Dog@1650c3
deepak.Cat@1650c4
---------------------END-------------------
Tuesday, May 31, 2011
Singleton pattern and Volatile in java
Dear reader,
Here is the complete example with test cases of Singleton Pattern in java.
Conditions of Singleton pattern:
1) One and only one instance of that Class.
2) Can't be cloned as cloning creates a new object violating Design principles of SingletonPattern.
3) Any sub-class of Singleton class should not be allowed as there is a default constructor in Sub-class
and using that multiple objects can be created. So Singleton class should have private default
constructor to avoid getting invoked using super() from sub-class constructor.
4) Make instance variable as Volatile. volatile ensures that multiple threads handle the object correctly
when it is being initialized in the SingletonPattern. For more details about "volatile", please see
at the end of this article.
5) Also, it should be designed in such a way that even after De-Serialization too, same object should be
returned. As making serialization and de-serialization multiple instances can be created. I have given
an example for this too.
//Full example (SingletonPattern.java)
public class SingletonPattern {
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
}
//Main test class (SingletonMain.java)
================Tries to extend SingletonClass: Prohibited================
/*public class SingletonMain extends SingletonPattern {
public SingletonMain(){} //Not allowed, as super class constructor is private.
public static void main(String[] args) {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
}
}
*/
/*public class SingletonMain extends SingletonPattern { //Not allowed as it assumes a default constructor
//Constructor code is not written here. //should be there in super class.
public static void main(String[] args) {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
}
}
*/
================Tries to clone SingletonClass: Prohibited================
//Now your class need to implement Cloneable Interface and then only use the below
//code, else it will throw exception. Because if a class doesn't implement Cloneable,
//it can't be cloned.
public class SingletonMain implements Cloneable {
public static void main(String[] args) throws Exception {
SingletonPattern obj=SingletonPattern.getInstance();
System.out.println(obj);
SingletonPattern main=(SingletonPattern)(obj.clone()); //Will throw exception, cloning is prohibited.
System.out.println(main);
}
}
//Output when run SingletonMain class
SingletonPattern@360be0
Exception in thread "main" java.lang.CloneNotSupportedException: Cloning of this class is not allowed
at SingletonPattern.clone(SingletonPattern.java:17)
at SingletonMain.main(SingletonMain.java:25)
============================volatile===========================
Making instance volatile ensures that mulitple threads handle the object correctly when it is being
initialized to the SingletonPattern class.
To Understand example of volatile keyword in java let’s go back to Singleton pattern in Java and see
double checked locking in Singleton with Volatile and without volatile keyword in java.
------------------
//This example is representation of Singleton Pattern discussed above
public class SingletonPattern {
private static volatile SingletonPattern _instance;
public static SingletonPattern getInstance() {
if(_instance == null){
synchronized(SingletonPattern.class){
if(_instance == null)
_instance = new SingletonPattern();
}
}
return _instance;
}
}
------------------
If you look at the code carefully you will be able to figure out:
1) We are only creating instance one time
2) We are creating instance lazily at the time of first request comes.
If we do not make _instance variable volatile then Thread which is creating _instance of SingletonPattern is
not able to communicate other thread, that instance has been created until it comes out of the SingletonPattern
block, so if Thread A is creating SingletonPattern instance and just after creation lost the CPU, all other
threads will not be able to see value of "_instance" as not null and they will believe its still null.
Why because reader threads are not doing any locking and until writer thread comes out of synchronized
block, memory will not be synchronized and value of _instance will not be updated in main memory. With
Volatile keyword in Java this is handled by Java himself and such updates will be visible by all reader
threads.
=======Last point to get the same object afer De-Serialization============
Now suppose we want the above Singleton class to be serializable. We can implement the Serializable interface
for the above class and be done with it. But in that case we won’t be able to protect the singleton nature
of the instance, such that after de-serialization there will be more than one instance of the class.
This can be proved as follows:
Writing again the singleton pattern class:
////////////SingletonPattern.java
================================================
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SingletonPattern implements Cloneable, Serializable{
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
}
================================================
//////Main class to fetch SingletonPattern Object and do Serialization:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class TestMain {
public static void main(String[] args) throws Exception{
SingletonPattern object=SingletonPattern.getInstance();
System.out.println("Original Singleton Object: "+object);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(new File("out3.dat")));
out.writeObject(object);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File("out3.dat")));
SingletonPattern deserObject = (SingletonPattern) in.readObject();
//After de-serialization we will get different object
System.out.println("Deserialized Singleton Object: "+deserObject);
in.close();
//Returning false, should return true.
System.out.println("This shows false, should be true: "+(object == deserObject));
//Returning true.
System.out.println("This shows true: "+(object == SingletonPattern.getInstance()));
}
}
////Output:
Original Singleton Object: SingletonPattern@164eee
Deserialized Singleton Object: SingletonPattern@16a04a
This shows false, should be true: false
This shows true: true
================================================
You can analyze the output, two different Singleton Objects are there and equality shows FALSE.
This breaks the rule of Singleton class. The way to avoid this is using another hook, the readResolve()
method. The readResolve() method is called when the ObjectInputStream has read an object from the
stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the
object defines the readResolve() method. If the method is defined, the readResolve method is called to
allow any changes in the object before it is returned.
So now we will add the readResolve() method in SingletonPattern.java, the modified code is:
================================
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SingletonPattern implements Cloneable, Serializable{
private volatile static SingletonPattern object=null;
private SingletonPattern(){} //No subclass can be created because of this private default constructor.
public static SingletonPattern getInstance(){ //Never put synchronized in method, else other threads will be
//blocked for getting object.
if(object==null){ //Check instance, if there isn't one, enter a synchronized block.
synchronized (SingletonPattern.class) { //We only synchronized the first time through.
if(object==null){ //Once in the block, double check for null and create an instance.
object=new SingletonPattern();
}
}
}
return object;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
private Object readResolve() throws ObjectStreamException {
return getInstance();
}
}
================================
Now if you run the TestMain program again you will see output (it will show equality as TRUE) and
objects are equal. It means that even after de-serialization, we still have only one instance of the class in
our JVM.
==============
//Output
Original Singleton Object: SingletonPattern@164efe
Deserialized Singleton Object: SingletonPattern@164efe
This shows false, should be true: true
This shows true: true
==============
--------------------------------END-----------------------------------
Thursday, July 8, 2010
Facade Design pattern
Facade pattern hides the complexities of the system and provides an interface to the client using which the
client can access the system. Call Center people are representation of entire product which company promotes.
This pattern adds an interface to existing system to hide its complexities.
The interface JDBC can be called a facade. We as users or clients create connection using the “java.sql.Connection”
interface, the implementation of which we are not concerned about. The implementation is left to the vendor of driver.
-------------------------------------------------------
public interface Shape {
void draw();
}
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Rectangle:: draw()");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Square:: draw()");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Circle:: draw()");
}
}
public class ShapeMaker {
private Shape circle;
private Shape rectangle;
private Shape square;
public ShapeMaker() {
circle = new Circle();
rectangle = new Rectangle();
square = new Square();
}
public void drawCircle(){
circle.draw();
}
public void drawRectangle(){
rectangle.draw();
}
public void drawSquare(){
square.draw();
}
}
//Main Program
public class FacadePatternDemo {
public static void main(String[] args) {
ShapeMaker shapeMaker = new ShapeMaker();
shapeMaker.drawCircle();
shapeMaker.drawRectangle();
shapeMaker.drawSquare();
}
}
Code: https://www.tutorialspoint.com/design_pattern/facade_pattern.htm
Subscribe to:
Posts (Atom)