Creational Patterns
These patterns help when object creation becomes repetitive, complex, or dependent on runtime choices.
Singleton
One shared instance
Real-world example: one application-wide logger or configuration manager.
Logger a = new Logger();
Logger b = new Logger();class Logger {
static Logger getInstance() { ... }
}
Logger logger = Logger.getInstance();Factory Method
Create objects through a chooser
Real-world example: return `EmailNotifier` or `SmsNotifier` based on user settings.
if (type == "sms") notifier = new SmsNotifier();
else notifier = new EmailNotifier();Notifier makeNotifier(type) {
return type == "sms" ? new SmsNotifier() : new EmailNotifier();
}Builder
Step-by-step object construction
Real-world example: building a `Report` with title, filters, charts, and export options.
new Report("Sales", true, false, "pdf", ...);Report report = new ReportBuilder()
.title("Sales")
.withChart()
.build();Prototype
Clone from an existing template
Real-world example: duplicate a dashboard layout with the same widgets and tweak a few settings.
Dashboard copy = new Dashboard();
// repeat all widget setup againDashboard copy = dashboardTemplate.clone();
copy.setTheme("dark");Facade
One clean entry point
Real-world example: a `TravelBookingService` that hides flight, hotel, payment, and ticket generation details.
flight.book();
hotel.reserve();
payment.pay();
ticket.send();tripService.bookTrip(user, from, to, dates);Adapter
Make incompatible APIs fit
Real-world example: adapt a third-party payment SDK to your own `PaymentGateway` interface.
// client depends directly on externalSdk.makePayment(...)gateway.charge(amount);
// adapter forwards to external SDKDecorator
Add behavior without changing the base class
Real-world example: wrap a file reader with caching, then compression, then encryption.
EncryptedCachedCompressedFileReader reader;Reader reader =
new EncryptedReader(new CachedReader(new FileReader()));Composite
Treat groups and single items uniformly
Real-world example: a folder can contain files and other folders, but both expose the same operations like `size()`.
if (item is File) ...
else if (item is Folder) ...int total = rootFolder.size();
// same call for file or folder