How do I implement the Factory Method pattern in Java?

The Factory Method pattern is a Gang of Four (GoF) creational design pattern. It defines an operation for creating a product while allowing subclasses to choose the concrete product returned. This lets a base class reuse a workflow without hard-coding the product implementation into that workflow.

This article continues our creational patterns series after Singleton. Here, we focus on choosing an implementation through subclassing.

The problem

Suppose an application sends notifications by email and SMS. Both channels support the same operation, send(), but each has its own implementation.

We want a notification service to follow a shared workflow: create a notification, then send the message. The shared workflow should work with either channel. Factory Method gives subclasses a creation step to customize.

A complete example

Save the following code as FactoryMethodExample.java. The classes are nested so that the entire example fits into one source file. In a larger application, you can place them in separate files.

package org.kodejava.pattern.factorymethod;

public class FactoryMethodExample {
    interface Notification {
        void send(String message);
    }

    static class EmailNotification implements Notification {
        @Override
        public void send(String message) {
            System.out.println("Email: " + message);
        }
    }

    static class SmsNotification implements Notification {
        @Override
        public void send(String message) {
            System.out.println("SMS: " + message);
        }
    }

    abstract static class NotificationService {
        protected abstract Notification createNotification();

        public void notifyUser(String message) {
            Notification notification = createNotification();
            notification.send(message);
        }
    }

    static class EmailNotificationService extends NotificationService {
        @Override
        protected Notification createNotification() {
            return new EmailNotification();
        }
    }

    static class SmsNotificationService extends NotificationService {
        @Override
        protected Notification createNotification() {
            return new SmsNotification();
        }
    }

    public static void main(String[] args) {
        NotificationService email = new EmailNotificationService();
        email.notifyUser("Your order has been shipped.");

        NotificationService sms = new SmsNotificationService();
        sms.notifyUser("Your verification code is 482731.");
    }
}

The channel implementations print messages to the console to keep the example self-contained. They do not contact an email provider or SMS gateway.

Compile and run from the directory containing the source file:

javac -d out FactoryMethodExample.java
java -cp out org.kodejava.pattern.factorymethod.FactoryMethodExample

Output:

Email: Your order has been shipped.
SMS: Your verification code is 482731.

How it works

The example has four roles:

GoF role Example Responsibility
Product Notification Declares the operation shared by all notifications.
Concrete products EmailNotification, SmsNotification Implement the channel behavior.
Creator NotificationService Declares the factory method and uses its result in a shared workflow.
Concrete creators EmailNotificationService, SmsNotificationService Override the factory method to choose a concrete product.

The factory method is createNotification(). The inherited notifyUser() method calls it and uses the returned Notification without needing to know its concrete class.

Java supports this structure through abstract methods and method overriding: each concrete service supplies the creation behavior declared by its abstract superclass. See Java’s documentation on abstract methods and classes.

The client still selects a concrete service in main(). The pattern moves product creation behind an overridable method; it does not eliminate the need to choose which service the application uses.

Adding another channel

To support push notifications, implement Notification in a new PushNotification class. Then extend NotificationService and override createNotification() to return that product. The existing notifyUser() workflow can remain unchanged.

This example creates a new product for each call. Factory Method itself does not require a new instance every time; an implementation can return a reusable product if its lifecycle and thread-safety requirements allow it.

Factory Method versus a simple factory

A utility such as NotificationFactory.create("email"), with a conditional selecting a concrete class, is commonly called a simple factory. That can be useful, but it does not demonstrate the subclass-based creation mechanism shown here.

In this example, the defining relationship is that the creator’s shared workflow invokes a factory method overridden by its subclasses. Merely naming a method create() does not establish that structure.

When should I use it?

Use Factory Method when a base class has useful shared behavior, but subclasses need to customize the products that behavior uses. It is especially suitable for extension points in frameworks or reusable libraries.

The tradeoff is additional classes and inheritance. If all you need is a small conditional that constructs an object, a simple factory may be sufficient. If callers can supply an already-created Notification, constructor injection may provide a simpler way to customize the behavior.

Next in this series: Abstract Factory, which focuses on creating families of related products.

How do I implement a Singleton pattern?

Singleton Pattern is used when we want to allow only a single instance of a class can be created inside our application. This pattern ensures that a class only have a single instance by protecting the class creation process, which can be done by defining the class constructor with private access modifier.

To get an instance of a singleton we provide a getInstance() method, this will be the only method that can be accessed to get an instance of the singleton class.

package org.kodejava.pattern.factory;

public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        return instance;
    }

    public void doSomething() {
        for (int i = 0; i < 10; i++) {
            System.out.println("i = " + i);
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException("Clone is not allowed.");
    }
}

There are some rules that need to be followed when we want to implement a singleton.

  • From code above we can see that a singleton has a static variable to keep it sole instance.
  • We need to set the class constructor into private access modifier. By this we will not allow any other class to create an instance of this singleton because they have no access to the constructor.
  • Because no other class can instantiate this singleton how can we use it? the answer is the singleton should provide a service to it users by providing some method that returns the instance, for example getInstance().
  • When we use our singleton in a multi threaded application we need to make sure that instance creation process not resulting more that one instance, so we add a synchronized keywords to protect more than one thread access this method at the same time.
  • It is also advisable to override the clone() method of the java.lang.Object class and throw CloneNotSupportedException so that another instance cannot be created by cloning the singleton object.

And this is how we use the singleton class.

package org.kodejava.pattern.factory;

public class SingletonDemo {
    public static void main(String[] args) {
        // Gets an instance of Singleton class and calls the
        // doSomething method.
        Singleton singleton = Singleton.getInstance();
        singleton.doSomething();
    }
}