Factory Pattern and the Java Class Object

Overview

The Factory Pattern is a Software Design Pattern that is used to create an object without calling the specific object’s constructor.  This pattern allows a end user to call the factory to instantiate a class without having to know how to instantiate the class itself.  How it works is by the creation of a Factory object that contains a get method that returns an Object based on the parameters inputted to it.

To illustrate the pattern imagine you have a database that contains rules that need to be run every so often to ensure the integrity of your system. Next less also assume that each Rule could potentially be a different class but they all implement a common interface with the method execute. Using the Factory Pattern would be a good choice to go with as it would enable you to create new rules without having your engine know what it is running.

In Java we can utilize the Class object to make it so that our factory itself would not have to know about every Rule that it could create. This is done by utilizing the forName and newInstance methods. The Class.forName method takes as a parameter the name of a class and returns a Class Object for the specified class, and if it can’t find the class it throws a ClassNotFoundException. Using the Class Object returned from the forName method we can then call newInstance to instantiate the object.

Now to guarantee that you are instantiating a rule object and not just any object you could make use of an interface. This way when you instantiate the class you can cast it as the interface, and if this object doesn’t implement the interface then a ClassCastExeption would be thrown.

Java Example

Rule Intrface

package com.mdbitz

/*
 * Import Statements
 */
import java.util.List;

public interface IRule {
	
    /**
     * This is a set of init params which will be used 
     * to seed the rule
     * 
     * @param initParams
     */
    public void init(List initParams) 
                            throws IllegalArgumentException; 
    
    /**
     * This is the main business method of the rule
     * @return
     */
    public Boolean execute();
    
}

RuleFactory

package com.mdbitz;

/**
 * This class is a factory which instantiates the rules
 *
 */
public class RuleFactory{
  
    
    /**
     * Private constructor to enforce that it cannot be 
     * instantiated
     *
     */
    private RuleFactory(){
        super();
    }
    
    /**
     * This method initializes a Rule Class
     * @param Name of the Class
     * @return IRule
     */
    public static IRule getRule( String className )
    throws ClassNotFoundException,ClassCastException,
    IllegalAccessException,InstantiationException{
        IRule rule = null;
        try{
           Class implementationClass = Class.forName(className);
	   rule = (IRule)implementationClass.newInstance();
	   if(!implementationClass.isInstance(rule)){
	       throw new ClassCastException(
                      rule.getClass().getName()+ 
                      " is incompatible with "+className);
	   } 
        }catch(ClassNotFoundException cnfe){
	     throw new ClassNotFoundException( 
                      "In RuleFactory >> "+ruleClassName+
                      " not found",cnfe );
	 }catch(ClassCastException cce){
	     throw new ClassCastException(
                      "In RuleFactory >>" +ruleClassName+
                      " does not implement required interface" + 
                      " IRulen In"+cce.getMessage() );
	 }
         return rule;
    }    
    
}

Calling the Factory

RuleFactory.getRule( "com.mdbitz.SpecificRule" );

Comments & Questions

Add Your Comment