About Debadatta Mishra

I am working as a Technical Architect at JDA Software. I have more than 7 years of industrial experience in the field of Java, XML, Web services, Cloud and Banking and Financial and Logistics domain. I have contributed many articles on Java in internet sites.

Factory Design Pattern – An Effective Approach

As you know the Factory Method Pattern or popularly known as the Factory Design Pattern is one the design patterns under the category of “Creational Design Pattern”. The basic principle behind the pattern is that at runtime we get an object of similar type based on the parameter we pass. There are many articles on this pattern and developers implement in various ways to achieve it. In this article I will show you how to create a better and most effective way of designing factory design pattern.

Technicalities

As I have told you we will get a similar type object at run-time in the case of a factory design so that the underlying implementation of an object will be behind the screen. Let us consider a simple approach. Let’s consider a Person object that can be either Male or Female. At runtime we should only consider the behavior of the person but not the gender. As the traditional approach we create a Person interface and we create two implementation classes like MalePerson and FemalePerson. Based upon the runtime gender data, we pass to a Factory method of a Factory class where we decide whether the gender type is Male or Female and accordingly we create the instance of the particular class and return the reference type object. This approach sounds good and we adopt it in many of our developmental activities. Can we ensure that it is the effective approach in the case of fine-grained multi-threaded applications. What about the performance? Is there any other approach? Yes we do.

Let’s consider another real time example. Think about a situation in an organization where an employee can be CEO, CTO, CFO, Developer, Test Engineer, HR, Personnel, Security etc. If you want to know the role of an employee based upon the organization, what will you do ? How will you create a better factory design so that we can easily find the role and there should not be performance penalty ? Will you adopt the same traditional approach by providing multiple if clauses ? You can make an argument that , we should use switch condition. Fine… Let us see traditional approach and let us measure the time.

Let us employ our factory design in a traditional manner.

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public interface Roles 
{
	public String getRole();
}

The above interface is used as a type as there can be various types of role in the organization. It has a method called “getRole()” that specifies the description of the role of the employee.

Let’s design the implementation classes for the suitable roles for CEO, CTO, and CFO in an organization.

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public class CEORoles implements Roles 
{
	public String getRole() 
	{
		return "CEO is the supreme head of the company";
	}
}

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public class CFORoles implements Roles
{
	@Override
	public String getRole() 
	{
		return "CFO is the finance head of a company";
	}
}

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public class CTORoles implements Roles
{
	@Override
	public String getRole() 
	{
		return "CTO is the technology decision maker of a company";
	}
}

Now we have to think about the Factory from where we will the Object dynamically. Let us see the code below.

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public abstract class EmployeeFactory
{
	public static Roles getRole( String type )
	{
		Roles roles = null;
		if( type.equals("cfo"))
			roles = new CFORoles();
		else if( type.equals("cto"))
			roles = new CTORoles();
		else if( type.equals("ceo"))
			roles = new CEORoles();
		return roles;
	}
}

Let us write a simple test harness class to verify the design.

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public class TestTraditionalFactoryDesign 
{
	public static void main(String[] args) 
	{
		String type = "ceo";
		long startTime = System.nanoTime();
		String role = EmployeeFactory.getRole(type).getRole();
		System.out.println("Role ::: "+role);
		long endTime = System.nanoTime();
		System.out.println("Time difference ::: "+(endTime-startTime)+" nano seconds");
	}

}

If you run the above program, the following is the output from my system.

For you information, my system has 4 GB RAM and I5 processor.

Role ::: CEO is the supreme head of the company
Time difference ::: 3477574 nano seconds

The above design seems to be correct , but what about performance ? You may say it does not matter because it comes in terms of nano seconds. Of course it does not matter if your application is very small , but it really matters in case of large enterprise applications. if you are a good programmer or developer you can not ignore the performance issue, particularly in case of product development where ther may be similar products in the market.

To address the above issue, let us try another approach of factory design where there may be changes in the factory class.

Let us see the code below.

package com.ddlab.rnd.patterns;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public enum EmployeeType 
{
	CEO("CEO") 
	{
		@Override
		public Roles getRoles() 
		{
			return new CEORoles();
		}
	},

	CTO("CTO")
	{
		@Override
		public Roles getRoles() {

			return new CTORoles();
		}
	},

	CFO("CFO")
	{
		@Override
		public Roles getRoles() {

			return new CFORoles();
		}
	};

	private EmployeeType( String type )
	{
		this.type = type;
	}

	private String type;
	public abstract Roles getRoles();

	public String getType() 
	{
		return type;
	}

	@Override
	public String toString() 
	{
		return "TYPE CODE -> "+type;
	}
}

The test harness class is given below.

package com.ddlab.rnd.patterns;
import java.util.HashMap;
import java.util.Map;
/**
 * @author Debadatta Mishra(PIKU)
 *
 */
public class TestFactoryDesign 
{
	static Map<String,EmployeeType> typeMap = new HashMap<String,EmployeeType>();

	static
	{
		typeMap.put("cto", EmployeeType.CTO);
		typeMap.put("ceo", EmployeeType.CEO);
		typeMap.put("cfo", EmployeeType.CFO);
	}

	public static void main(String[] args)
	{
		String empType = "ceo";
		try 
		{
			long startTime = System.nanoTime();
			String whatIstheRole = typeMap.get(empType).getRoles().getRole();
			System.out.println("Role of the Employee :::"+whatIstheRole);
			long endTime = System.nanoTime();
			System.out.println("Time difference ::: "+(endTime-startTime)+" nano seconds");
		}
		catch (NullPointerException e) 
		{
			System.out.println("No such Role is found");
			e.printStackTrace();
		}
	}
}

If you run the above code, you will get the following output.

Role ::: CEO is the supreme head of the company
Time difference ::: 1049108 nano seconds

What about the time. Let use have comparision between the time taken in the traditional approach and the modern approach.

Traditional Approach3477574 nano seconds
Modern Approach(using enum and Map)1049108 nano seconds

Can you think about the time difference, it is just about 3 times faster than the traditional approach.

So which is better ? Of course the modern approach of using enum is better. Apart from enum, I have used Map to maintain the list of employee type and its corresponding enum. In this case there is no need to use if clause which may impact our performance as far cyclomatic complexity is concerned. It is always better to use the above approach of 1049108 nano seconds. You can use ConcurrentMap for your multi threaded application.

Conclusion

I hope you will enjoy my article on the factory design pattern. In case of any clarification you can contact me debadatta.mishra@gmail.com.
 

Reference: Factory Design Pattern – An Effective Approach from our JCG partner Debadatta Mishra at the Debadatta Mishra blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

4 Responses to "Factory Design Pattern – An Effective Approach"

  1. Balaji T says:

    But here you have the type map at the test class, but it is out of the time measurement. What about the time taken for putting the objects in the map? It also should be taken into account right for time measurement!

  2. An0nym0usC0ward says:

    Three times faster isn’t a significant difference. You have to find a way to evaluate your algorithm’s complexity. In terms of role counts, both of your algorithms are O(n), which is pretty good. What really matters is a difference in the algorithms complexity. For example, if you find a mechanism which is only O(ln(n)) in terms of role counts, you’re way better off, in terms of scalability.

  3. Secret Agent says:

    Interesting approach.

  4. jay says:

    Thanks for modern approach

Leave a Reply


+ four = 11



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close