Skip to main content

Applying Creational Design Patterns in Java

October 28, 2009

{cs.r.title}







Design patterns, made famous by the "gang of four" (GOF), as they are fondly called (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides), are a collection of proven steps to be followed for a particular type of problem in software scenario. Java Design patterns provide a time tested solution which can be applied to a set of problems (the problems will have a common set of characteristics) to come to a solution. Obviously, the solution should be optimal in terms of execution.

Among the different categories of Java Design Patterns available, this article will focus on "Creational Design Patterns", which focus on the creation of objects in Java from a class or group of classes. The patterns present under the umbrella of Creational Design Patterns basically define:

  • How the Objects will be instantiated
  • How many Objects will be instantiated
  • At what point the Objects will be instantiated

Creational design patterns contain the following design patterns:

  1. Factory Method Pattern
  2. Abstract Factory Pattern
  3. Singleton Pattern
  4. Builder Pattern
  5. Prototype Pattern

This article covers each of these patterns, includes examples that show how to implement the patterns, and describes under which circumstances each of the patterns can be applied.

Factory Method Design Pattern

The factory method pattern is used when we have group of classes and one class needs to be instantiated to represent the user data. Which class to instantiate depends upon the user data. So, basically we have a class factory, and an object will be the product.

Which class's object will come out of the factory is abstracted from the user, as to the user it's just the information that is contained in the object that is shown.

There is a class, which contains a method which will take the user data and create an object of one of the class out of group of classes. This class is called the Factory Class and hence the name 'Factory Method Design Pattern'.

Let us elaborate this with an example. Consider the scenario where we have an abstract Account class which has three subclasses that extend it, namely: SavingsAccount, RecurringAccount, and FixedDeposit.

Figure 1 is the Class Diagram for the Account class.


Figure 1. Class diagram for the Account class.

The three subclasses that extend this class provide the definition of the methods.

OpenAccount is a factory class which has a method for creating an object of one of the subclasses, depending upon the value of attribute type that is provided by the user. The created object is then returned back to the user.

Listing 1 is the source code for this Factory class scenario.

Listing 1. Source code for the factory method implementation

Instances when you should consider using the Factory Method pattern include:

  • when the object creation depends upon the user data or some event;
  • when which object is getting created is abstracted from the user;
  • when the type of object created is to be decided at runtime.

Abstract Factory Design Pattern

This pattern is used when we have an object to be returned out of group of objects. The group of objects belong to the same theme. This returned object acts like a factory, which therefore returns another object to the user.

The pattern has an interface, which is implemented by different classes to form the group of objects all coming from the same interface. There is one product class whose object is to be created in the end.

The group of classes created each contain different methods, each returning an object of type Product. We'll explain this with an example. Suppose we are writing a program related to investments such as stocks, bonds, and derivatives. In this example the product is Amount. So, let's create an Abstract Class Amount.

This Amount class is extended by three more classes namely: Premium, EMI, and Principal. We have an interface Investment which is implemented by three classes, namely: Stocks, Bonds, and Derivatives.

The class diagram of for the product Amount and abstract class Investment is shown in Figure 2.

       

Figure 2. Class diagram for Amount and Investment.

The source code for the Abstract Factory class is provided in Listing 2.

Listing 2. Source code for the abstract factory implementation.

Thus, abstract factories first return an object out of group of objects, then this object further returns an object out of a set of possibilies, depending upon the user's input. Another way of saying this: the Abstract Factory pattern encapsulates a group of factories, each object out of which itself acts as in independent factory.

Consider using the Abstract Factory method in the following situations:

  • when a lot of subclasses are supposed to be added at runtime or later in the application;
  • when one type of object encapsulates other type of object;
  • when the System should work with the product without being aware of the specific classes interfacing with the product.

Singleton Design Pattern

The Singleton Design Pattern restricts number of occurrences of an object of a class to one. When we want only one object of a particular class to be created and used by all in the other modules so that the concurrency of the data held by the object is maintained, we use the Singleton Pattern. Here are steps to be followed to implement the Singleton Design Pattern:

  • Declare a class and declare a static member variable of type class inside it.
  • Make the constructor private.
  • Create a method which will instantiate the static member variable if it is null otherwise return the old created object.

Consider a logging function that used to log the statements in a large enterprise application. We want to have only one logger for the entire application and share it across the whole code. Below is the implementation of this scenario.

Let's create a class Logger on which we will apply the singleton pattern. Figure 3 presents the class diagram.


Figure 3. Logger class diagram.

Listing 3 is the code to be implemented.

Listing 3. Source code for the singleton implementation

Builder Design Pattern

This pattern is used to create object by combining a group of objects together internally. The pattern assembles a number of objects depending upon the user input and brings out a complex objects. The Builder Pattern is different from Abstract Pattern as it brings out a complex object while the later gives a factory returning a simple object. Figure 4 makes things little clearer.


Figure 4. Builder design pattern illustration.

We have three components classes A, B, and C. There is a builder class which will take the user input and based on that input will roll out a complex objects containing the component objects in a defined manner.

Let's consider an example that isn't from the software engineering field. We go to a restaurant and order for a milk shake. There can be many types of shakes available. The cook here acts as the builder. Depending upon our input he/she takes different components, namely ice, milk, fruit or ice cream, etc., and comes back with a complex object Shake which is different for different inputs from the user.

Taking another example from software engineering: consider a scenario where we have to make a Web interface that differs depending upon the user. The different components of the webpage will be:

  • Header
  • Footer
  • Managers Dashboard
  • Forum column
  • Gallery
  • Common Display area

When the manager logs into the system, and we have to show the Web interface for the manager. So we have builder class which will take following components and make the UI:

Header, Footer, Gallery, Manager's Dashboard.

Similarly, for other types of users we can have different combinations of the possible components displayed, giving each type of user a customized UI.

Consider using the Builder Design Pattern in the following situations:

  • when a complex object has to be made and the implementation has to be hidden from the user;
  • when we want to add more subclasses to our system without the user's knowledge.

Prototype Design Pattern

The Prototype Design Pattern is used when we have an object of a particular class already available, and creation of a new object is a costly affair in terms of memory, resources, and operations involved. We simply clone the object that's already available, to get an exact replica of the object; then we work on the cloned object to get the required result. To make this possible, the class must implement the 'Cloneable interface'.

Consider a scenario where we have sent a query to Database to extract information on all the employees. Now the user wants to see the information on all the managers in the organization. Instead of sending a new query to the database for managers, we clone the existing object containing the information on all the employees, and filter the data set so only the manager details will be displayed to the user.

The concept of cloning is demonstrated in email client UIs, where we sort the emails on different criteria. Listing 4 presents an example of the code to be implemented.

Listing 4. Source code for the prototype implementation.

The code shows that the first time the object is created, and the next time we call the clone method we get the same object back with same data contained in it. We modify the data (by appending "Second Object") to it and display it to the user.

Consider using the Prototype Pattern in the following situations:

  • when the user interface is not to be changed; for example, a dropdown remains a dropdown, or a Radio Button remains a Radio Button, no matter what data has to be displayed;
  • when creating a new object is a costly affair;
  • when the data to be displayed is already present in some other object.

Conclusion: Design Patterns Application Decisions

Most of the time in the software engineering scenario, it is beneficial to use more than one design pattern for a situation, as that typically yields a momre optimal result. Hence the patterns discussed here can be applied to multiple problems and situations, and it is left up to the application designer or architect to decide which specific patterns to apply and where to apply them.


width="1" height="1" border="0" alt=" " />
Varun Sood is currently working as Senior Associate-Education at Infosys Technologies Limited. His areas of interest include Enterprise Architecture and Web Application Security. Varun is as SCJP 6.0 certified programmer.
Related Topics >> Patterns   |   Programming   |   Featured Article   |   

Comments

I think the examples in the

I think the examples in the article could have been simpler.

Factory method: when using a constructor is too convoluted


class ShapeFactory {

// use to instantiate from database or something
public Shape createShape(String type) {
if ("square".equals(type)) return new Square();
else if ("triangle".equals(type)) return new Triangle();
else if ....
...
}
}


Hate the if/else from the previous example? See AbstractFactory.

Abstract Factory: when I have many to create but each needs to be created differently.

class ShapeFactory {

// use to instantiate from database or something
public Shape createShape(String type) {
AbstractShapeFactory f = _factories.get(type);
return f.create();
}

ShapeFactory() {
_factories.put("square", new SquareFactory());
_factories.put("sphere", new SphereFactory());
...
}

}

interface AbstractShapeFactory {
public Shape create();
}

class SquareFactory implements AbstractShapeFactory {
public Shape create() {
return new Square();
}
}

Singleton: When there can be only one.
(Note: provided example was not very good with thread safety)

final class OnlyOne {
private OnlyOne _theOne = new OnlyOne();
private OnlyOne() {}

public static OnlyOne getInstance() {
return _theOne;
}
}

Builder: When it can take several steps.

SQLBuilder b = new SQLBuilder();
b.setTable("account");
b.addColumn("id");
b.addColumn("name");
b.setCriteria(Criteria.equals("id", 5)); //using a static factory method to build criteria
String s = b.build(); // creates a string: SELECT id, name FROM account WHERE id = 5


Prototype: Instead of AbstractFactory.

class ShapeFactory {

// use to instantiate from database or something
public Shape createShape(String type) {
Shape s = _prototypes.get(type);
return s.copy(); // use copy() instead of clone().. clone doesn't have consistent semantic meaning
}

ShapeFactory() {
_prototype.put("square", new Square());
_prototype.put("sphere", new Sphere());
...
}

}


I like the way you write. I

I like the way you write. I will recommend your articles to my colleagues. Please write more on Design Patterns. Your writing style can save juniors from long hours and days of reading other Design Patterns books.

Thanks a lot for your

Thanks a lot for your appreciation.
I will surely be writting more on implementation side of design patterns shortly