Design Pattern in Java

What is the design pattern?

If a problem occurs over and over again, a solution to that problem has been used effectively. That solution is described as a pattern. The design patterns are language-independent strategies for solving common object-oriented design problems. When you make a design, you should know the names of some common solutions. Learning design patterns is good for people to communicate each other effectively. In fact, you may have been familiar with some design patterns, you may not use well-known names to describe them. SUN suggests GOF (Gang Of Four–four pioneer guys who wrote a book named “Design Patterns”- Elements of Reusable Object-Oriented Software), so we use that book as our guide to describe solutions. Please make you be familiar with these terms and learn how other people solve the code problems.


Use the Design pattern?

If you want to be a professional Java developer, you should know at least some popular solutions to coding problems. Such solutions have been proved efficient and effective by the experienced developers. These solutions are described as so-called design patterns.

Many programmers with many years experience don’t know design patterns, but as an Object-Oriented programmer, you have to know them well, especially for new Java programmers. Actually, when you solved a coding problem, you have used a design pattern. You may not use a popular name to describe it or may not choose an effective way to better intellectually control over what you built. Learning how the experienced developers to solve the coding problems and trying to use them in your project are a best way to earn your experience and certification.

 

Remember that learning the design patterns will really change how you design your code; not only will you be smarter but will you sound a lot smarter, too.


What is the relationship among these patterns?

 

Generally, to build a system, you may need many patterns to fit together. Different designer may use different patterns to solve the same problem. Usually:

  • Some patterns naturally fit together
  • One pattern may lead to another
  • Some patterns are similar and alternative
  • Patterns are discoverable and documentable
  • Patterns are not methods or framework
  • Patterns give you hint to solve a problem effectively

 


References

The Design Patterns, Java Companion — by James W. Cooper

Sun’s core J2EE Patterns

 


Singleton

Definition

One instance of a class or one value accessible globally in an application.


Where to use & benefits

  • Ensure unique instance by defining class final to prevent cloning.
  • May be extensible by the subclass by defining subclass final.
  • Make a method or a variable public or/and static.
  • Access to the instance by the way you provided.
  • Well control the instantiation of a class.
  • Define one value shared by all instances by making it static.

To implement Singleton pattern, we have different approaches but all of them have following common concepts.

  • Private constructor to restrict instantiation of the class from other classes.
  • Private static variable of the same class that is the only instance of the class.
  • Public static method that returns the instance of the class, this is the global access point for outer world to get the instance of the singleton class.

How to Create Singleton Class :

public class Singleton {

    private static Singleton instance;
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton();
        }
        return instance;
    }
}

 


Lazy instantiation using double locking mechanism.

The standard implementation shown in the above code is a thread safe implementation, but it’s not the best thread-safe implementation beacuse synchronization is very expensive when we are talking about the performance. We can see that the synchronized method getInstance does not need to be checked for syncronization after the object is initialized. If we see that the singleton object is already created we just have to return it without using any syncronized block. This optimization consist in checking in an unsynchronized block if the object is null and if not to check again and create it in an syncronized block. This is called double locking mechanism.

In this case case the singleton instance is created when the getInstance() method is called for the first time. This is called lazy instantiation and it ensures that the singleton instance is created only when it is needed.

//Lazy instantiation using double locking mechanism.
class Singleton
{
	private static Singleton instance;

	private Singleton()
	{
	System.out.println("Singleton(): Initializing Instance");
	}

	public static Singleton getInstance()
	{
		if (instance == null)
		{
			synchronized(Singleton.class)
			{
				if (instance == null)
				{
					System.out.println("getInstance(): First time getInstance was invoked!");
					instance = new Singleton();
				}
			}            
		}

		return instance;
	}

	public void doSomething()
	{
		System.out.println("doSomething(): Singleton does something!");
	}
}

Thread Safe Singleton 

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;
    
    private ThreadSafeSingleton(){}
    
    public static synchronized ThreadSafeSingleton getInstance(){
        if(instance == null){
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }
    
}

Factory Method

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

 

  • Connect parallel class hierarchies.
  • A class wants its subclasses to specify the object.
  • A class cannot anticipate its subclasses, which must be created.
  • A family of objects needs to be separated by using shared interface.
  • The code needs to deal with interface, not implemented classes.
  • Hide concrete classes from the client.
  • Factory methods can be parameterized.
  • The returned object may be either abstract or concrete object.
  • Providing hooks for subclasses is more flexible than creating objects directly.
  • Follow naming conventions to help other developers to recognize the code structure.

Drawbacks and Benefits

Here are the benefits and drawbacks of factory method pattern:

  • + The main reason for which the factory pattern is used is that it introduces a separation between the application and a family of classes (it introduces weak coupling instead of tight coupling hiding concrete classes from the application). It provides a simple way of extending the family of products with minor changes in application code.
  • + It provides customization hooks. When the objects are created directly inside the class it’s hard to replace them by objects which extend their functionality. If a factory is used instead to create a family of objects the customized objects can easily replace the original objects, configuring the factory to create them.
  • – The factory has to be used for a family of objects. If the classes doesn’t extend common base class or interface they can not be used in a factory design template.

 


Example :

The participants classes in this pattern are:

  • Product defines the interface for objects the factory method creates.
  • ConcreteProduct implements the Product interface.
  • Creator(also refered as Factory because it creates the Product objects) declares the method FactoryMethod, which returns a Product object. May call the generating method for creating Product objects
  • ConcreteCreator overrides the generating method for creating ConcreteProduct objects

All concrete products are subclasses of the Product class, so all of them have the same basic implementation, at some extent. The Creator class specifies all standard and generic behavior of the products and when a new product is needed, it sends the creation details that are supplied by the client to the ConcreteCreator. Having this diagram in mind, it is easy for us now to produce the code related to it. Here is how the implementation of the classic Factory method should look:

public interface Product {  }

public abstract class Creator 
{
	public void anOperation() 
	{
		Product product = factoryMethod();
	}
	
	protected abstract Product factoryMethod();
}

public class ConcreteProduct implements Product {  }

public class ConcreteCreator extends Creator 
{
	protected Product factoryMethod() 
	{
		return new ConcreteProduct();
	}
}

public class Client 
{
	public static void main( String arg[] ) 
	{
		Creator creator = new ConcreteCreator();
		creator.anOperation();
	}
}

Doubleton

What is a Doubleton Class ?

For any java class if we are allowed to create at-most two objects, such type of class is called as ‘Doubleton Class’.

How to create Class :

package in.concept.learning.centre;

public class DoubleTon {
	private static DoubleTon instance1;
	private static DoubleTon instance2;

	
	private DoubleTon(){}
	
	public static DoubleTon getInstance() {
		if (instance1 == null) {
			instance1 = new DoubleTon();
			return instance1;
		} else if (instance2 == null) {
			instance2 = new DoubleTon();
			return instance2;
		} else {
			if (Math.random() < 0.5) {
				return instance1;
			} else {
				return instance2;
			}
		}
	}

	public static void main(String[] args) {
			System.out.println(DoubleTon.getInstance());
			System.out.println(DoubleTon.getInstance());
			System.out.println(DoubleTon.getInstance());
			System.out.println(DoubleTon.getInstance());
	}
}

Output :

in.concept.learning.centre.DoubleTon@1db9742
in.concept.learning.centre.DoubleTon@106d69c
in.concept.learning.centre.DoubleTon@106d69c
in.concept.learning.centre.DoubleTon@106d69c

Tripleton

What is a Tripleton Class ?

For any java class if we are allowed to create at-most Three objects, such type of class is called as ‘Tripleton Class’.

How to create Class :

package in.concept.learning.centre;

public class TripleTon {

	private static TripleTon limInstance;
	public static int objCount = 0;

	private TripleTon() {
		objCount++;
	}

	public static synchronized TripleTon getLimInstance() {
		if (objCount < 3) {
			limInstance = new TripleTon();
		}
		return limInstance;
	}

	public static void main(String[] args) {

		TripleTon obj1 = TripleTon.getLimInstance();
		TripleTon obj2 = TripleTon.getLimInstance();
		TripleTon obj3 = TripleTon.getLimInstance();
		TripleTon obj4 = TripleTon.getLimInstance();
		TripleTon obj5 = TripleTon.getLimInstance();
		TripleTon obj6 = TripleTon.getLimInstance();

		System.out.println(obj1);
		System.out.println(obj2);

		System.out.println(obj3);
		System.out.println(obj4);
		System.out.println(obj5);
		System.out.println(obj6);
	}

}

Output :

in.concept.learning.centre.TripleTon@1db9742
in.concept.learning.centre.TripleTon@106d69c
in.concept.learning.centre.TripleTon@52e922
in.concept.learning.centre.TripleTon@52e922
in.concept.learning.centre.TripleTon@52e922
in.concept.learning.centre.TripleTon@52e922