Friday, 26 October 2007

Factory Pattern in Java

Problem: Problem of creating objects without specifying the exact class of object that will be created.The new operator considered harmful. There is a difference between requesting an object and creating one.

The new operator always creates an object, and fails to encapsulate object creation.
A Factory Method enforces that encapsulation, and allows an object to be requested without inextricable coupling to the act of creation. [Amsterdam, p19]

Main Purpose: Any method responsible for creating objects.Hence we need a mechanism where we can achieve polymorphism in its purest form.

Factory Design Pattern: Defines seperate method for creating objects which subclasses can override to specify specific behaviour.Factory Method is to creating objects same as Template Method is to implementing an algorithm.
Factory Method makes a design more customizable and only a little more complicated. Other design patterns require new classes, whereas Factory Method only requires a new operation. [GoF, p136]

People often use Factory Method as the standard way to create objects; but it isn't necessary if the class that's instantiated never changes, or instantiation takes place in an operation that subclasses can easily override (such as an initialization operation). [GoF, p136]

The advantage of a Factory Method is that it can return the same instance multiple times, or can return a subclass rather than an object of that exact type. [Davis, p4]

Few Advantages of Factory pattern

Distintive Names:

Factory Methods can have Distintive Names.

public class Shape {
private Shape() {}

public static Shape createShapeFromRectangle() {
......
// Ideally we will have subclasses for Rectangle and Triangle
}

public static Shape createShapeFromTriangle() {
......
// Ideally we will have subclasses for Rectangle and Triangle
   }

}
Shape s=Shape.createShapeFromRectangle();


Encapsulation:
Another advantage of factory pattern is it encapsulates the process of creating the objects.

public class ShapeFactory {

static ShapeFactory shapeFactory;

private ShapeFactory() {}

static {
shapeFactory=new ShapeFactory();
}

// Actually implClass to be used is derived from properties file.Though it is not the best example
// it describes one way of achieveing encapsulation.

public static Shape createShape() {

// One way is to Retrieve From Properties file shape.impl className.
// shape.impl=packageName.RectangleImpl.class

Shape implShapeClass=resourceHandler.getValue(getClass(), "shape.impl");
return Class.forName(implShapeClass).newInstance();
   }
}

We can even change the concept of loading from properties file and pass a parameter to createShape() method by which we can derive the subclass to be instantiated.

Limitations:
a) Refactoring may not work as it may break code who uses the standard
methodology of creating objects by calling constructors.

b) Factory Classes may not be inherited as we made the decision to make constructor private .
We made obviously this decision to restrict subclasses to provide their own implementation for factory methods.

Finally when we refer GOF book the intent advice is:
Define an interface for creating an object, but let subclasses decide which class to instantiate.
Factory Method lets a class defer instantiation to subclasses. [GoF, p107]

Example - One typical use of the Factory Pattern in an Enterprise JavaBean (EJB) Application: An entity bean is an object representation of persistent data that are maintained in a permanent data store, such as a database. A
primary key identifies each instance of an entity bean. Entity beans can be created by creating an object using an object factory Create method. Similarly, Session beans can be created by creating an object using an object
factory Create method.

Another typical use of the Factory Pattern in the Common Object Request Broker Architecture (CORBA):The CORBA Object Services - Naming Service Specification (COSNaming), describes the entire namespace in terms of NamingContext Objects. These contexts can be connected to each other and can contain references to actual object instances for which clients will ask. The contexts are all contained within the CosNaming.Factory and CosNaming.ExtFactory servers. When the factory server is executed, it always creates a singleton persistent object implementing the CosNaming::NamingContextFactory interface. All NamingContext objects created within a particular factory server are associated with that server's single NamingContextFactory. The factories support the following interfaces as shown in Listing 2:

// CORBA Interface Definition Language
module CosNaming {

interface NamingContextFactory {

NamingContext create_context ();
oneway void shutdown ();
};

interface ExtendedNamingContextFactory : NamingContextFactory {

NamingContext root_context ();
   };

};

Hope this explanation helps.

3 comments:

Anonymous said...

The explanation given here is good enough to understand the meaning of factory pattern,but how can this be achieved in say a jsp page where for eg there is html:select with many options in it and we want to populate the options comming from a factory,where the values are stored...to eliminate the lines of code.

JP said...

Hi,

I think in this scenario we may go for html:optionsCollection and make the collection in the background as immutable -SingletonList.

subbus said...

how you are loading objects from property file i didn't get that part