Photo by Andreas Felske on Unsplash
In my previous article, I stated the need for creational patterns and illustrated them using two creational patterns: Factory Method Pattern and Builder Pattern. So in short creational patterns focus on creating objects in a way that promotes encapsulation, decoupling, and flexibility.
In this article, we will look at the following two design patterns in detail
-
Singleton pattern
-
Prototype pattern
Singleton Pattern
Singleton pattern are used to make sure that only one instance of a class is created and provides global access to it. It uses a private constructor to prevent direct object instantiation and the static method provides access to the single instance.

Singleton Class (Same User behind every door)
Lets us look at an example:
1public class Logger {
2 private static Logger instance;
3
4 // Private constructor to prevent direct instantiation
5 private Logger() {
6 // Initialization code, if needed
7 }
8
9 // Static method to provide access to the single instance
10 public static Logger getInstance() {
11 if (instance == null) {
12 instance = new Logger();
13 }
14 return instance;
15 }
16
17 // Method to log a message
18 public void log(String message) {
19 System.out.println("Logging message: " + message);
20 // Log message implementation goes here
21 }
22}In the example above Logger class has a private constructor Logger and getInstance method which provides a single instance of the class.
1public class Main {
2 public static void main(String[] args) {
3 Logger logger = Logger.getInstance();
4 logger.log("An important message");
5
6 // Trying to create a new instance will give us the existing instance
7 Logger anotherLogger = Logger.getInstance();
8 anotherLogger.log("Another message");
9
10 // Output:
11 // Logging message: An important message
12 // Logging message: Another message
13 }
14}The above example states that only one instance of the class gets created regardless of the number of times getInstance() is called.
The singleton pattern ensures that all the components share the same logger instance. This helps in centralized logging and ensures all messages are recorded by the same logger object.
Thus singleton pattern is used when one instance of an object needs to be created and has to be shared across other components.
Prototype pattern
Prototype pattern allows the creation of objects by cloning existing instances thereby reducing the need to create new instances from scratch. It has a prototype object and uses that object to create new objects by cloning. It is used when new object creation is expensive and complex.
Photo by Kumpan Electric on Unsplash
Let's consider a scenario where we have a design application that can create and customize shapes. Prototype pattern is used to clone the existing shape objects and modify them as per requirement instead of creating each shape object from scratch.
1// Prototype interface
2public interface Shape extends Cloneable {
3 void draw();
4 Shape clone();
5}
6
7// Concrete implementation of Shape
8public class Circle implements Shape {
9 private int radius;
10
11 public Circle(int radius) {
12 this.radius = radius;
13 }
14
15 @Override
16 public void draw() {
17 System.out.println("Drawing a circle with radius " + radius);
18 }
19
20 @Override
21 public Shape clone() {
22 try {
23 return (Shape) super.clone();
24 } catch (CloneNotSupportedException e) {
25 return null;
26 }
27 }
28}
29
30// Client code
31public class GraphicDesignApp {
32 public static void main(String[] args) {
33 // Create a prototype circle
34 Circle circlePrototype = new Circle(10);
35
36 // Clone the circle and customize
37 Shape circle1 = circlePrototype.clone();
38 circle1.draw();
39
40 ((Circle) circle1).setRadius(15);
41 circle1.draw();
42
43 // Clone the circle again and customize
44 Shape circle2 = circlePrototype.clone();
45 ((Circle) circle2).setRadius(8);
46 circle2.draw();
47 }
48}The shape interface has the clone and draw method. The circle class implements the interface and has its modification of the radius field.
In the GraphicDesignApp circlePrototype object is created and new circle objects are created by cloning and modifying the radius and then draw() is called to visualize it.
Do note that clone() in Java performs a shallow copy. If there are mutable fields a deep copy must be performed to create a cloned object.
Thus prototype pattern is useful when creating complex objects and each object requires a variation. It makes use of the existing object to reduce the overhead of object creation.
Do note that each creational design pattern has its own set of requirements and constraints.Hope the above explanations and implementation examples give you clarity on the creational designer pattern.Happy creating objects !!!
