Creational Design Patterns

Naveen AnamaneniUpdated · 8 min read

Writing new looks harmless, but every new SomeClass() ties your code to that exact class. If you later need a different class, a shared object, or a carefully assembled one, you end up editing new calls all over the program. Creational patterns are five tried ways of making objects so that the rest of your code doesn't have to care how they're made. This lesson walks through all five in plain terms, each with a small program you can run.

The Five at a Glance

PatternThe problemThe idea
SingletonThere must be exactly one of somethingThe class makes its one object and hands it to everyone
Factory MethodA general class doesn't know which object its subclasses will needLeave one "create" method for each subclass to fill in
Abstract FactorySeveral objects must always match each otherOne factory makes the whole matching set
BuilderAn object has many optional partsChoose the parts step by step, then build once
PrototypeMaking an object from scratch is slow or fiddlyCopy a ready-made one and change what differs

Singleton

Some things should exist only once in a program, like the app's settings. A singleton class makes its constructor private, creates its one object itself, and gives everyone that same object. In Java, the safest way is an enum with a single value. The full story, including thread safety, is in "Singleton Pattern in Java".

SingletonDemo.java▶ Try it
public class SingletonDemo {
    enum AppSettings {
        INSTANCE;
        private String currency = "INR";
        String currency() { return currency; }
    }
 
    public static void main(String[] args) {
        AppSettings a = AppSettings.INSTANCE;
        AppSettings b = AppSettings.INSTANCE;
        System.out.println(a == b);
        System.out.println(a.currency());
    }
}
Output
true
INR

Factory Method

Picture a courier company. Every branch delivers parcels the same way (pick up, carry, drop off), but the road branch uses trucks and the port branch uses ships. The parent class writes the delivery steps once and leaves a single method, "which vehicle?", for each branch to answer. That method is the factory method.

Couriers.java▶ Try it
public class Couriers {
    interface Transport { String carry(String parcel); }
 
    static class Truck implements Transport {
        public String carry(String parcel) { return parcel + " goes by road"; }
    }
 
    static class Ship implements Transport {
        public String carry(String parcel) { return parcel + " goes by sea"; }
    }
 
    abstract static class Branch {
        abstract Transport createTransport();
 
        String deliver(String parcel) {
            return createTransport().carry(parcel);
        }
    }
 
    static class RoadBranch extends Branch {
        Transport createTransport() { return new Truck(); }
    }
 
    static class PortBranch extends Branch {
        Transport createTransport() { return new Ship(); }
    }
 
    public static void main(String[] args) {
        System.out.println(new RoadBranch().deliver("Navika's laptop"));
        System.out.println(new PortBranch().deliver("Advitha's furniture"));
    }
}
Output
Navika's laptop goes by road
Advitha's furniture goes by sea

How it works

  1. Branch.deliver is written once and never mentions Truck or Ship.
  2. It calls createTransport(), the factory method, which each subclass fills in.
  3. Adding an air branch means one new subclass; deliver stays the same.

This is different from the simpler "factory" in "Factory Pattern in Java", where one method uses a switch to choose. Here, subclasses make the choice. Java's own collections do this: every collection's iterator() method creates the right kind of iterator for that collection.

Abstract Factory

Some objects only make sense together. A light-themed app needs light buttons and light checkboxes; mixing a dark button into a light screen looks broken. An abstract factory is one object that makes the whole matching family, so you can't mix them up by accident.

Themes.java▶ Try it
public class Themes {
    interface Button { String draw(); }
    interface Checkbox { String draw(); }
 
    interface ThemeFactory {
        Button button();
        Checkbox checkbox();
    }
 
    static class LightTheme implements ThemeFactory {
        public Button button() { return () -> "white button"; }
        public Checkbox checkbox() { return () -> "white checkbox"; }
    }
 
    static class DarkTheme implements ThemeFactory {
        public Button button() { return () -> "black button"; }
        public Checkbox checkbox() { return () -> "black checkbox"; }
    }
 
    static void drawScreen(ThemeFactory theme) {
        System.out.println(theme.button().draw()
            + " next to a " + theme.checkbox().draw());
    }
 
    public static void main(String[] args) {
        drawScreen(new LightTheme());
        drawScreen(new DarkTheme());
    }
}
Output
white button next to a white checkbox
black button next to a black checkbox

How it works

  1. ThemeFactory promises a button and a checkbox.
  2. LightTheme and DarkTheme each make a set that matches.
  3. drawScreen only knows ThemeFactory, so it always gets a matching pair. Switching the whole app's theme means passing a different factory.
  4. () -> "white button" is a lambda, a short way to write a small object for an interface with one method. Lambdas get their own lessons later in the course.

Builder

When an object has many optional parts, a constructor with eight arguments becomes impossible to read. A builder lets you set each part by name, in any order, and then call build() once at the end, where the whole thing is checked. "Builder Pattern in Java" covers it fully.

BuilderDemo.java▶ Try it
public class BuilderDemo {
    public static void main(String[] args) {
        String note = new StringBuilder("Dear Srihitha,")
            .append(" your order")
            .append(" has shipped.")
            .toString();
        System.out.println(note);
    }
}
Output
Dear Srihitha, your order has shipped.

StringBuilder is the builder you've already used: you add the parts one at a time, then toString() builds the finished string.

Prototype

Imagine printing invitations for a function. You design one card carefully, then photocopy it and only change the guest's name. Prototype works the same way: keep one ready-made object and create new ones by copying it, instead of setting everything up from scratch each time.

Invitations.java▶ Try it
public class Invitations {
    static class Invitation {
        private final String event;
        private final String venue;
        private final String guest;
 
        Invitation(String event, String venue, String guest) {
            this.event = event;
            this.venue = venue;
            this.guest = guest;
        }
 
        Invitation copyFor(String newGuest) {
            return new Invitation(event, venue, newGuest);
        }
 
        @Override
        public String toString() {
            return event + " at " + venue + ", for " + guest;
        }
    }
 
    public static void main(String[] args) {
        Invitation template = new Invitation("Annual Day", "City Hall", "");
        for (String guest : new String[] {"Navika", "Srihitha", "Advitha"}) {
            System.out.println(template.copyFor(guest));
        }
    }
}
Output
Annual Day at City Hall, for Navika
Annual Day at City Hall, for Srihitha
Annual Day at City Hall, for Advitha

The template is set up once, and each copy only changes the guest. Java's built-in version of this idea is clone() (see "Object Cloning in Java"), but a simple copy method like copyFor is usually clearer.

Common Mistakes

Using a Singleton as a convenient global variable. It makes code hard to test; pass shared objects in where you can.

Confusing Factory Method with a simple factory. In Factory Method, subclasses decide; in a simple factory, one method with a switch decides.

Shallow copies in Prototype. If the template holds a list, copy the list too, or every copy shares it.

Interview Corner

What are the creational design patterns?

They're the five patterns about object creation. Singleton ensures a class has only one instance. Factory Method lets subclasses decide which class to instantiate through an overridable creation method. Abstract Factory creates families of related objects that belong together. Builder constructs complex objects step by step. Prototype creates new objects by copying an existing one.

What is the difference between Factory Method and Abstract Factory?

Factory Method is a single overridable method that creates one kind of product, with each subclass choosing the concrete class. Abstract Factory is an object with several creation methods that produce a whole family of related products, such as a matching button and checkbox for one theme.

Practice

  1. Easy: Add an AirBranch to Couriers.java that delivers parcels by plane.
  2. Harder: Add a Slider to Themes.java, so each theme factory also makes a matching slider, and draw it on the screen.

Quick check: Creational patterns

4 questions
1Which pattern makes new objects by copying an existing one?
2Which pattern makes a whole family of matching objects?
3In Factory Method, who decides which class is created?
4Which creational pattern is StringBuilder an example of?

Key Takeaways

Was this tutorial helpful?

Lesson 179 of 482