Exploring Creational Design Patterns in Real-Life Applications: From Singleton to Prototype
Creational design patterns in Java provide ways to create objects while abstracting the instantiation process. This article delves into the Singleton, Factory Method, Abstract Factory, Builder, and Prototype patterns, demonstrating their application in real-life scenarios.
1. Singleton Pattern
When to Use:
Why to Use:
Example Use Case:
public class Singleton {
private static Singleton instance;
private Singleton() {
// private constructor to prevent instantiation
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2. Factory Method Pattern
When to Use:
Why to Use:
Example Use Case:
abstract class Document {
public abstract void open();
}
class WordDocument extends Document {
@Override
public void open() {
System.out.println("Opening Word document");
}
}
class PDFDocument extends Document {
@Override
public void open() {
System.out.println("Opening PDF document");
}
}
abstract class DocumentFactory {
public abstract Document createDocument(String type);
}
class ConcreteDocumentFactory extends DocumentFactory {
@Override
public Document createDocument(String type) {
if (type.equals("Word")) {
return new WordDocument();
} else if (type.equals("PDF")) {
return new PDFDocument();
} else {
throw new IllegalArgumentException("Unknown document type");
}
}
}
3. Abstract Factory Pattern
When to Use:
Why to Use:
领英推荐
Example Use Case:
interface Button {
void paint();
}
class WindowsButton implements Button {
public void paint() {
System.out.println("Rendering a button in a Windows style");
}
}
class MacOSButton implements Button {
public void paint() {
System.out.println("Rendering a button in a macOS style");
}
}
interface GUIFactory {
Button createButton();
}
class WindowsFactory implements GUIFactory {
public Button createButton() {
return new WindowsButton();
}
}
class MacOSFactory implements GUIFactory {
public Button createButton() {
return new MacOSButton();
}
}
4. Builder Pattern
When to Use:
Why to Use:
Example Use Case:
class Car {
private String engine;
private String wheels;
private String body;
private Car(CarBuilder builder) {
this.engine = builder.engine;
this.wheels = builder.wheels;
this.body = builder.body;
}
public static class CarBuilder {
private String engine;
private String wheels;
private String body;
public CarBuilder setEngine(String engine) {
this.engine = engine;
return this;
}
public CarBuilder setWheels(String wheels) {
this.wheels = wheels;
return this;
}
public CarBuilder setBody(String body) {
this.body = body;
return this;
}
public Car build() {
return new Car(this);
}
}
}
5. Prototype Pattern
When to Use:
Why to Use:
Example Use Case:
interface Prototype extends Cloneable {
Prototype clone();
}
class UserSession implements Prototype {
private String userName;
private String userPreferences;
public UserSession(String userName, String userPreferences) {
this.userName = userName;
this.userPreferences = userPreferences;
}
@Override
public Prototype clone() {
return new UserSession(userName, userPreferences);
}
@Override
public String toString() {
return "UserSession [userName=" + userName + ", userPreferences=" + userPreferences + "]";
}
}
Summary