Saturday, February 7, 2009

Factory Pattern

This is a Creational pattern, so this pattern can be used to hide the object instantiation process.
Simply, if we have a super class and set of sub-classes, and based on data provided, we have to return the object of one of the sub-classes, we use a factory design pattern to solve this.

Just get an idea by watching this video.



Let's think that we have set of shapes Line, Square, Circle and we need to draw the shape as per the request from the client. In other words based on the data provided by the client.

A Shape is an interface. Several implementing classes(Line, Square, Circle) may be designed in the following way.

//Shape interface which will be implemented by
Line, Square, Circle classes.
interface Shape {
public void draw();
}

//Line class implementation
class Line implements Shape {
Point x, y;
Line(Point a, Point b) {
x = a;
y = b;
}
public void draw() {
//draw a line;
}
}

//Square class implementation
class Square implements Shape {
Point start;
int width, height;
Square(Point s, int w, int h) {
start = s;
width = w;
height = h;
}
public void draw() {
//draw a square;
}
}

//Circle class implementation
class Circle implements Shape {
....
}

class ShapeFactory{
public getShape(){
Shape shape=null;
if(isLine){
shape =new Line(int x, int y);
}
else if(isSquare){
shape =new Square(int x, int y, int z);
}
else
shape =new Circle(int x, int y);
}
}

//Client calling code will be like this,
ShapeFactory fac=new ShapeFactory();
Shape s=fac.getShape(int x, int y)
s.draw();// this will draw a line

Shape s=fac.getShape(int x, int y, int z)
s.draw();// this will draw a Square

Shape s=fac.getShape(int x, int y)
s.draw();// this will draw a Circle

Please note that the above code is not complete.


Real World Example

To illustrate how to use factory design pattern with class level implementation, here is a real world example. A company has a website to display testing result from a plain text file. Recently, the company purchased a new machine which produces a binary data file, another new machine on the way, it is possible that one will produce different data file. How to write a system to deal with such change. The website just needs data to display. Your job is to provide the specified data format for the website.

Here comes a solution. Use an interface type to converge the different data file format. The following is a skeleton of implementation.

//Let's say the interface is Display
interface Display {

//load a file
public void load(String fileName);

//parse the file and make a consistent data type
public void formatConsistency();

}

//deal with plain text file
class CSVFile implements Display{

public void load(String textfile) {
System.out.println("load from a txt file");
}
public void formatConsistency() {
System.out.println("txt file format changed");
}
}

//deal with XML format file
class XMLFile implements Display {

public void load(String xmlfile) {
System.out.println("load from an xml file");
}
public void formatConsistency() {
System.out.println("xml file format changed");
}
}

//deal with binary format file
class DBFile implements Display {

public void load(String dbfile) {
System.out.println("load from a db file");
}
public void formatConsistency() {
System.out.println("db file format changed");
}
}

//Test the functionality
class TestFactory {

public static void main(String[] args) {
Display display = null;

//use a command line data as a trigger
if (args[0].equals("1"))
display = new CSVFile();
else if (args[0].equals("2"))
display = new XMLFile();
else if (args[0].equals("3"))
display = new DBFile();
else
System.exit(1);

//converging code follows
display.load("");
display.formatConsistency();
}
}
//after compilation and run it

C:\>java TestFactory 1
load from a txt file
txt file format changed

C:\>java TestFactory 2
load from an xml file
xml file format changed

C:\>java TestFactory 3
load from a db file
db file format changed

In the future, the company may add more data file with different format, a programmer just adds a new class in accordingly. Such design saves a lot of code and is easy to maintain.




Related links to Factory pattern

Intro to Design Patterns: Factory Method Pattern
Java Design Patterns Factory Method

No comments:

Post a Comment

Followers