Factory Method Design Pattern in Java

Factory Method Design Pattern: Description

Factory method design pattern belongs to creational patterns. This pattern is also known as virtual constructor pattern. This pattern is designed to create an object in a smart way, smart way in the sense that in general, we use new operator in Java to create an object but the new operator can only be used when the client application knows in advance which class's object has to be created?

At times, among subclasses in a class hierarchy (where subclasses may override the parent class's method to offer a different type of functionality for the same method) client application may only know that it needs to access a class from within the class hierarchy, but does not know exactly which class among the set of subclasses of the parent class is to be selected. And here, FACTORY METHOD DESIGN PATTERN proves to be useful.

A simple factory method design pattern creates an object of one of several possible classes in inheritance hierarchy depending on the data provided to it. In this pattern, client application does not specify the class name whose object is to be created rather it provides some data to factory method in order to create an object and factory method itself decides which class's object should be created on behalf of the data provided to it.
The most challenging part in this pattern is to implement the class selection criteria to instantiate an appropriate class from the hierarchy to create an object.

Factory Method Design Pattern: Coding Example

In factory method design pattern mainly three classes/interfaces are involved, first, the factory class that creates an object from a given class hierarchy, second, an interface which is implemented by the concrete classes; objects of those classes will be created by factory class depending upon the input parameters, and third, an application object that creates one or more objects of interface's implementer classes with the help of factory class in order to use them for its purpose.

Here, we are coding a simple factory method design pattern. We are developing a functionality to log messages for an application. In order to implement logging functionality by using factory method design pattern we define a Java interface Logger that will be used to create references by the client objects to log messages and will be implemented by concrete logger classes. Interface Logger has a method logMessage that will be implemented by ConsoleLogger and FileLogger. ConsoleLogger will display log messages on console, while FileLogger will direct log messages to a text file.

There will be a third class Factory that will be used to create objects of FileLogger or ConsoleLogger. Driver class FactoryMethodPattern will use the services provided by the Logger implementers (ConsoleLogger and FileLogger). Application message logging configuration is specified by using the logger.properties property file, which has a field FileLogging = ON/OFF.

Depending upon the value of the FileLogging property, an appropriate Logger implementer needs to be used to log messages. For example, if the FileLogging property is set to ON, messages are to be logged to a file and hence a FileLogger object can be used to log messages. Similarly, if the FileLogging property is set to OFF, messages are to be displayed on the console and hence a ConsoleLogger object can be used.

The following figure shows how various classes are associated to each other in factory method design pattern.

Factory Method Design Pattern
Fig. 1 - Factory Method Design Pattern (Class Diagram).

Following program presents Java code for above class diagram of factory method design pattern. To execute the following piece of code you have to create a text file logger.properties within the same directory your .java program file is stored containing a line FileLogging = ON or FileLogging = OFF.

If you keep FileLogging = ON, log messages will be recorded in a text file Filelog.log in the same directory your program is being executed from. If Filelog.log is already present there, log messages will be appended to existing file else Filelog.log will be created by the program.

import java.io.File;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Properties;
 
interface Logger
{
  public void logMessage(String message);
}
 
class FileLogger implements Logger
{
  public void logMessage(String message)
  {
    try
    {
      File file =new File("Filelog.log");
 
      //create file if doesn't exist 
      if(!file.exists())
      {
        file.createNewFile();
      }
 
      //true = append file
      FileWriter fileWritter = new FileWriter(file.getName(),true);
      BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
      bufferWritter.write(message);
      bufferWritter.close();
    }
    catch(IOException e)
    {
      e.printStackTrace();
    }
    System.out.println("Message logged in file: " + message);
  }
}
 
class ConsoleLogger implements Logger
{
  public void logMessage(String message)
  {
    System.out.println("Console: " + message);
  }
}
 
class Factory
{
  public Logger getLogger()
  {
    if (isFileLoggingEnabled()) 
    {
      return new FileLogger();
    } 
    else 
    {
      return new ConsoleLogger();
    }
  }
 
  // helper method, check if FileLogging is ON
  // if so, log message to a file else print it to console.
  private boolean isFileLoggingEnabled() 
  {
    Properties p = new Properties();
    try 
    {
      p.load(ClassLoader.getSystemResourceAsStream("logger.properties"));
      String fileLoggingValue = p.getProperty("FileLogging");
      if (fileLoggingValue.equalsIgnoreCase("ON") == true)
        return true;
      else
        return false;
	} 
    catch (IOException e) 
    {
      return false;
    }
  }
}
 
class FactoryMethodPattern
{
  public static void main(String args[])
  {
    Factory f = new Factory();
    Logger msgLogger = f.getLogger();
    msgLogger.logMessage("Sample log message" + "\n");
  }
}

Above piece of code just demonstrates how factory method design pattern is developed. Choosing appropriate class from a hierarchy may be complex if different classes in the class hierarchy need to be instantiated in diverse manners.

Pros and Cons of Factory Method Design Pattern

  • In factory method design pattern, application object that intends to use the services offered by the class hierarchy needs to implement the class selection criteria, and as soon selection criteria is changed application object that uses the class hierarchy must undergo a corresponding change. This high degree of coupling between an application object and the service provider class hierarchy makes factory method design a change prone pattern and not considered good for frequently changed applications.
  • Factory method design pattern requires an application object to be fully aware of the existence and the functionality offered by each class in the service provider class hierarchy.

Last Word

In this tutorial we presented factory method design pattern. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!

References

  1. Design Patterns: Elements of Reusable Object-Oriented Software


Share this page on WhatsApp

Get Free Tutorials by Email

About the Author

is the founder and main contributor for cs-fundamentals.com. He is a software professional (post graduated from BITS-Pilani) and loves writing technical articles on programming and data structures.