Add per-pattern README.md for the 5 creational patterns (Factory Method, Abstract Factory, Builder, Prototype, Singleton) for consistency with all other 18 patterns
This commit is contained in:
33
01-creational/abstract-factory/README.md
Normal file
33
01-creational/abstract-factory/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Abstract Factory Design Pattern — Java Example
|
||||||
|
|
||||||
|
**Pattern:** Creational → Abstract Factory
|
||||||
|
**Article:** https://ankurm.com/abstract-factory-design-pattern-java/
|
||||||
|
|
||||||
|
## What this example shows
|
||||||
|
|
||||||
|
A UI toolkit that produces families of related widgets — light theme or dark theme — without the client ever naming a concrete class. `Button` and `TextField` are abstract products; `LightButton`/`LightTextField` and `DarkButton`/`DarkTextField` are the two concrete product families. `UIFactory` declares the creation methods for the whole family; `LightThemeFactory` and `DarkThemeFactory` each produce one consistent family. `Application` is the client — it only depends on `UIFactory` and the abstract products, so swapping the entire theme is a one-line change. `Main` selects the factory via a system property.
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
javac abstract-factory/*.java -d out/abstract-factory
|
||||||
|
java -cp out/abstract-factory abstractfactory.Main
|
||||||
|
# or, for the dark theme family:
|
||||||
|
java -Dapp.theme=dark -cp out/abstract-factory abstractfactory.Main
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Java 25.
|
||||||
|
|
||||||
|
## Post Section ↔ File Mapping
|
||||||
|
|
||||||
|
| Post Section | File(s) |
|
||||||
|
|---|---|
|
||||||
|
| Part 1 — The Abstract Products: Button and TextField | `Button.java`, `TextField.java` |
|
||||||
|
| Part 2 — The Concrete Products (Light family) | `LightButton.java`, `LightTextField.java` |
|
||||||
|
| Part 2 — The Concrete Products (Dark family) | `DarkButton.java`, `DarkTextField.java` |
|
||||||
|
| Part 3 — The Abstract Factory: UIFactory Interface | `UIFactory.java` |
|
||||||
|
| Part 4 — The Concrete Factories | `LightThemeFactory.java`, `DarkThemeFactory.java` |
|
||||||
|
| Part 5 — The Client: Application | `Application.java`, `Main.java` |
|
||||||
|
|
||||||
|
Article: https://ankurm.com/abstract-factory-design-pattern-java/
|
||||||
|
All patterns: https://ankurm.com/design-patterns-java/
|
||||||
30
01-creational/builder/README.md
Normal file
30
01-creational/builder/README.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Builder Design Pattern — Java Example
|
||||||
|
|
||||||
|
**Pattern:** Creational → Builder
|
||||||
|
**Article:** https://ankurm.com/builder-design-pattern-java/
|
||||||
|
|
||||||
|
## What this example shows
|
||||||
|
|
||||||
|
An immutable `HttpRequest` assembled step by step instead of through a constructor with a dozen optional parameters. `HttpRequest` is the product — built once, never mutated afterward. `HttpClientConfig` is a director-style helper that encapsulates common request configurations so callers don't repeat the same builder calls. `Main` wires it together and shows the fluent builder chain in action.
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
javac builder/*.java -d out/builder
|
||||||
|
java -cp out/builder builder.Main
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Java 25.
|
||||||
|
|
||||||
|
## Post Section ↔ File Mapping
|
||||||
|
|
||||||
|
| Post Section | File(s) |
|
||||||
|
|---|---|
|
||||||
|
| Part 1 — The Product: HttpRequest (Immutable) | `HttpRequest.java` |
|
||||||
|
| Part 2 — The Director: Encapsulating Common Configurations | `HttpClientConfig.java` |
|
||||||
|
| Part 3 — Using the Builder: Client Code | `Main.java` |
|
||||||
|
|
||||||
|
Note: the Lombok `@Builder` example and the JDK standard-library snippets (`HttpRequest.newBuilder()`, `StringBuilder`, `ProcessBuilder`) are illustrative only — they are not part of this repository's runnable example.
|
||||||
|
|
||||||
|
Article: https://ankurm.com/builder-design-pattern-java/
|
||||||
|
All patterns: https://ankurm.com/design-patterns-java/
|
||||||
32
01-creational/factory-method/README.md
Normal file
32
01-creational/factory-method/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Factory Method Design Pattern — Java Example
|
||||||
|
|
||||||
|
**Pattern:** Creational → Factory Method
|
||||||
|
**Article:** https://ankurm.com/factory-method-design-pattern-java/
|
||||||
|
|
||||||
|
## What this example shows
|
||||||
|
|
||||||
|
A notification system where the "send" logic decides which channel object to create, instead of the client doing it with a switch statement. `Notification` is the product interface; `EmailNotification`, `SmsNotification`, and `PushNotification` are concrete products. `NotificationSender` declares the factory method and a template `send()` step shared by every channel; `EmailSender`, `SmsSender`, and `PushSender` each override the factory method to produce their own notification type. `NotificationService` is shown separately as the anti-pattern this pattern replaces — it is not called by `Main`. `Main` demonstrates the cost of adding a new channel (Slack) by adding one new product and one new creator, with zero changes to existing classes.
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
javac factory-method/*.java -d out/factory-method
|
||||||
|
java -cp out/factory-method factorymethod.Main
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Java 25.
|
||||||
|
|
||||||
|
## Post Section ↔ File Mapping
|
||||||
|
|
||||||
|
| Post Section | File(s) |
|
||||||
|
|---|---|
|
||||||
|
| The Problem: Object Creation Leaks Into Business Logic | `NotificationService.java` (anti-pattern shown for contrast — not called by `Main`) |
|
||||||
|
| Part 1 — The Notification Interface | `Notification.java` |
|
||||||
|
| Part 2 — The Concrete Notification Classes | `EmailNotification.java`, `SmsNotification.java`, `PushNotification.java` |
|
||||||
|
| Part 3 — The NotificationSender Class | `NotificationSender.java` |
|
||||||
|
| Part 4 — The Concrete Sender Subclasses | `EmailSender.java`, `SmsSender.java`, `PushSender.java` |
|
||||||
|
| Part 5 — Running It: Client Code and Output | `Main.java` |
|
||||||
|
| Adding a New Channel (Slack) | `SlackNotification.java`, `SlackSender.java` |
|
||||||
|
|
||||||
|
Article: https://ankurm.com/factory-method-design-pattern-java/
|
||||||
|
All patterns: https://ankurm.com/design-patterns-java/
|
||||||
32
01-creational/prototype/README.md
Normal file
32
01-creational/prototype/README.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Prototype Design Pattern — Java Example
|
||||||
|
|
||||||
|
**Pattern:** Creational → Prototype
|
||||||
|
**Article:** https://ankurm.com/prototype-design-pattern-java/
|
||||||
|
|
||||||
|
## What this example shows
|
||||||
|
|
||||||
|
Documents cloned from existing instances instead of rebuilt from scratch. `Copyable` declares the cloning contract. `DocumentMetadata` is a nested object that must be copied correctly for a clone to be truly independent of its source. `Document` is the concrete prototype, implementing a real (not shallow) copy. `DocumentRegistry` stores a set of ready-made prototypes that callers clone on demand instead of constructing from raw parameters. `Main` demonstrates cloning from the registry and confirms the clone and original don't share mutable state.
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
javac prototype/*.java -d out/prototype
|
||||||
|
java -cp out/prototype prototype.Main
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Java 25.
|
||||||
|
|
||||||
|
## Post Section ↔ File Mapping
|
||||||
|
|
||||||
|
| Post Section | File(s) |
|
||||||
|
|---|---|
|
||||||
|
| Part 1 — The Prototype Interface: Copyable | `Copyable.java` |
|
||||||
|
| Part 2 — The Nested Object: DocumentMetadata | `DocumentMetadata.java` |
|
||||||
|
| Part 3 — The Concrete Prototype: Document | `Document.java` |
|
||||||
|
| Part 4 — The Prototype Registry: DocumentRegistry | `DocumentRegistry.java` |
|
||||||
|
| Part 5 — Using the Prototype: Client Code | `Main.java` |
|
||||||
|
|
||||||
|
Note: the `ShallowVsDeepDemo` snippet (shallow vs. deep copy) and the `Cloneable`-based example are illustrative only — they are not part of this repository's runnable example.
|
||||||
|
|
||||||
|
Article: https://ankurm.com/prototype-design-pattern-java/
|
||||||
|
All patterns: https://ankurm.com/design-patterns-java/
|
||||||
34
01-creational/singleton/README.md
Normal file
34
01-creational/singleton/README.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Singleton Design Pattern — Java Example
|
||||||
|
|
||||||
|
**Pattern:** Creational → Singleton
|
||||||
|
**Article:** https://ankurm.com/singleton-design-pattern-java/
|
||||||
|
|
||||||
|
## What this example shows
|
||||||
|
|
||||||
|
Six different ways to implement a singleton, compiled and run side by side so their tradeoffs are directly comparable. `AppConfigEager` initializes at class-load time. `AppConfigNaiveLazy` defers initialization but is not thread-safe. `AppConfigSynchronized` fixes thread-safety at the cost of locking on every call. `AppConfigDCL` uses double-checked locking to avoid that per-call lock. `AppConfigHolder` uses the initialization-on-demand holder idiom for lazy, thread-safe initialization with no locking at all. `AppConfigEnum` uses a single-element enum, which the JVM guarantees is a singleton even against reflection and serialization attacks. `Main` exercises all six in one run.
|
||||||
|
|
||||||
|
## How to run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
javac singleton/*.java -d out/singleton
|
||||||
|
java -cp out/singleton singleton.Main
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Java 25.
|
||||||
|
|
||||||
|
## Post Section ↔ File Mapping
|
||||||
|
|
||||||
|
| Post Section | File(s) |
|
||||||
|
|---|---|
|
||||||
|
| Implementation 1 — Eager Initialization | `AppConfigEager.java` |
|
||||||
|
| Implementation 2 — Naïve Lazy Initialization | `AppConfigNaiveLazy.java` |
|
||||||
|
| Implementation 3 — Synchronized Method | `AppConfigSynchronized.java` |
|
||||||
|
| Implementation 4 — Double-Checked Locking | `AppConfigDCL.java` |
|
||||||
|
| Implementation 5 — Initialization-on-Demand Holder | `AppConfigHolder.java` |
|
||||||
|
| Implementation 6 — Enum Singleton | `AppConfigEnum.java` |
|
||||||
|
| Running All Six Implementations Together | `Main.java` |
|
||||||
|
|
||||||
|
Each implementation is renamed to its own class (e.g. `AppConfigEager`, `AppConfigHolder`) so all six can be compiled together in one package and compared directly. The "Breaking via Reflection," "Breaking via Serialization," and Spring `@Component` snippets are illustrative only — they are not part of this repository's runnable example.
|
||||||
|
|
||||||
|
Article: https://ankurm.com/singleton-design-pattern-java/
|
||||||
|
All patterns: https://ankurm.com/design-patterns-java/
|
||||||
Reference in New Issue
Block a user