# GoF Design Patterns in Java Complete runnable Java 25 implementations of all 23 Gang of Four design patterns. Each pattern has a dedicated article at [ankurm.com](https://ankurm.com/gof-design-patterns-java/) with a UML diagram, step-by-step explanation, and console output. ## Structure ``` design-patterns/ ├── 01-creational/ │ ├── factory-method/ │ ├── abstract-factory/ │ ├── builder/ │ ├── prototype/ │ └── singleton/ ├── 02-structural/ │ ├── adapter/ │ ├── bridge/ │ ├── composite/ │ ├── decorator/ │ ├── facade/ │ ├── flyweight/ │ └── proxy/ └── 03-behavioral/ ├── chain-of-responsibility/ ├── command/ ├── interpreter/ ├── iterator/ ├── mediator/ ├── memento/ ├── observer/ ├── state/ ├── strategy/ ├── template-method/ └── visitor/ ``` ## Prerequisites - Java 25+ (Eclipse Temurin recommended) - No build tool required — plain `javac` / `java` ## Run any pattern ```bash # Linux / macOS / Git Bash (Windows) javac 03-behavioral/strategy/*.java -d out/strategy java -cp out/strategy strategy.Main ``` ```cmd REM Windows Command Prompt javac 03-behavioral\strategy\*.java -d out\strategy java -cp out\strategy strategy.Main ``` ## Articles | Pattern | Category | Article | |---------|----------|---------| | Factory Method | Creational | https://ankurm.com/factory-method-design-pattern-java/ | | Abstract Factory | Creational | https://ankurm.com/abstract-factory-design-pattern-java/ | | Builder | Creational | https://ankurm.com/builder-design-pattern-java/ | | Prototype | Creational | https://ankurm.com/prototype-design-pattern-java/ | | Singleton | Creational | https://ankurm.com/singleton-design-pattern-java/ | | Adapter | Structural | https://ankurm.com/adapter-design-pattern-java/ | | Bridge | Structural | https://ankurm.com/bridge-design-pattern-java/ | | Composite | Structural | https://ankurm.com/composite-design-pattern-java/ | | Decorator | Structural | https://ankurm.com/decorator-design-pattern-java/ | | Facade | Structural | https://ankurm.com/facade-design-pattern-java/ | | Flyweight | Structural | https://ankurm.com/flyweight-design-pattern-java/ | | Proxy | Structural | https://ankurm.com/proxy-design-pattern-java/ | | Chain of Responsibility | Behavioral | https://ankurm.com/chain-of-responsibility-design-pattern-java/ | | Command | Behavioral | https://ankurm.com/command-design-pattern-java/ | | Interpreter | Behavioral | https://ankurm.com/interpreter-design-pattern-java/ | | Iterator | Behavioral | https://ankurm.com/iterator-design-pattern-java/ | | Mediator | Behavioral | https://ankurm.com/mediator-design-pattern-java/ | | Memento | Behavioral | https://ankurm.com/memento-design-pattern-java/ | | Observer | Behavioral | https://ankurm.com/observer-design-pattern-java/ | | State | Behavioral | https://ankurm.com/state-design-pattern-java/ | | Strategy | Behavioral | https://ankurm.com/strategy-design-pattern-java/ | | Template Method | Behavioral | https://ankurm.com/template-method-design-pattern-java/ | | Visitor | Behavioral | https://ankurm.com/visitor-design-pattern-java/ | ## Post ↔ Code Mapping Each article is split into multiple runnable parts. This section maps every post section to the exact file(s) in this repository, so you can jump straight from "what I just read" to "the file that implements it." Updated pattern-by-pattern as each article is verified against Java 25. ### Factory Method (`01-creational/factory-method/`) | 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` | Run it: ```bash javac 01-creational/factory-method/*.java -d out/factory-method java -cp out/factory-method factorymethod.Main ``` ### Abstract Factory (`01-creational/abstract-factory/`) | 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` | Run it: ```bash javac 01-creational/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 ``` ### Builder (`01-creational/builder/`) | 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. Run it: ```bash javac 01-creational/builder/*.java -d out/builder java -cp out/builder builder.Main ``` ### Prototype (`01-creational/prototype/`) | 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. Run it: ```bash javac 01-creational/prototype/*.java -d out/prototype java -cp out/prototype prototype.Main ``` ### Singleton (`01-creational/singleton/`) | 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. `Main.java` exercises all six in one run. The "Breaking via Reflection," "Breaking via Serialization," and Spring `@Component` snippets are illustrative only — they are not part of this repository's runnable example. Run it: ```bash javac 01-creational/singleton/*.java -d out/singleton java -cp out/singleton singleton.Main ``` ### Adapter (`02-structural/adapter/`) | Post Section | File(s) | |---|---| | Step 1 — Define the Target Interface | `PaymentGateway.java` | | Step 2 — The Adaptee (What You're Wrapping) | `StripeClient.java` | | Step 3 — The Object Adapter | `StripePaymentAdapter.java` | | Step 4 — The Client (Knows Nothing About Stripe) | `OrderService.java` | | Putting It Together: The Main Demo | `Main.java` | | Object Adapter vs Class Adapter | `StripePaymentClassAdapter.java` | Note: the `InputStreamReader` JDK-adapter snippet is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 02-structural/adapter/*.java -d out/adapter java -cp out/adapter adapter.Main ``` ### Bridge (`02-structural/bridge/`) | Post Section | File(s) | |---|---| | Step 1 — The Implementor Interface | `Device.java` | | Step 2 — Concrete Implementors (TV and Radio) | `TV.java`, `Radio.java` | | Step 3 — The Abstraction (RemoteControl) | `RemoteControl.java` | | Step 4 — Refined Abstraction (AdvancedRemote) | `AdvancedRemote.java` | | Wiring It Together: Main Demo | `Main.java` | Note: the "Class Explosion Problem — Visualised" pseudocode and the JDBC/SLF4J snippets are illustrative only — they are not part of this repository's runnable example. Run it: ```bash javac 02-structural/bridge/*.java -d out/bridge java -cp out/bridge bridge.Main ``` ### Composite (`02-structural/composite/`) | Post Section | File(s) | |---|---| | The Problem: Treating Leaves and Containers Uniformly | illustrative only — not part of this repository's runnable example | | Step 1 — The Component Interface | `FileSystemItem.java` | | Step 2 — The Leaf (File) | `File.java` | | Step 3 — The Composite (Directory) | `Directory.java` | | Building and Using the Tree | `Main.java` | Run it: ```bash javac 02-structural/composite/*.java -d out/composite java -cp out/composite composite.Main ``` ### Decorator (`02-structural/decorator/`) | Post Section | File(s) | |---|---| | Step 1 — Component Interface | `TextProcessor.java` | | Step 2 — Concrete Component | `PlainTextProcessor.java` | | Step 3 — Base Decorator | `TextDecorator.java` | | Step 4 — Concrete Decorators | `UpperCaseDecorator.java`, `TrimDecorator.java`, `ProfanityFilterDecorator.java` | | Stacking the Decorators — Order Matters | `Main.java` | Note: the JDK `InputStream`/`BufferedInputStream`/`GZIPInputStream` snippet is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 02-structural/decorator/*.java -d out/decorator java -cp out/decorator decorator.Main ``` ### Facade (`02-structural/facade/`) | Post Section | File(s) | |---|---| | The Subsystem (Complex, But Unchanged) — VideoFile | `VideoFile.java` | | The Subsystem (Complex, But Unchanged) — Codec interface | `Codec.java` | | The Subsystem (Complex, But Unchanged) — Concrete Codecs | `MPEG4CompressionCodec.java`, `OggCompressionCodec.java` | | The Subsystem (Complex, But Unchanged) — CodecFactory | `CodecFactory.java` | | The Subsystem (Complex, But Unchanged) — BitrateReader | `BitrateReader.java` | | The Subsystem (Complex, But Unchanged) — AudioMixer | `AudioMixer.java` | | The Facade | `VideoConversionFacade.java` | | Client Code: One Line | `Main.java` | Note: the SLF4J `LoggerFactory`, JDBC `DriverManager`, and Spring `JdbcTemplate` snippets under "Facade in the JDK and Real Frameworks" are illustrative only — they are not part of this repository's runnable example. Run it: ```bash javac 02-structural/facade/*.java -d out/facade java -cp out/facade facade.Main ``` ### Flyweight (`02-structural/flyweight/`) | Post Section | File(s) | |---|---| | Step 1 — The Flyweight (TreeType) | `TreeType.java` | | Step 2 — The Factory (TreeFactory) | `TreeFactory.java` | | Step 3 — The Context (Tree) | `Tree.java` | | Putting the Forest Together | `Main.java` | Note: the "Flyweight in the JDK: String Pool and Integer Cache" and "Measuring the Benefit" snippets are illustrative only — they are not part of this repository's runnable example. Run it: ```bash javac 02-structural/flyweight/*.java -d out/flyweight java -cp out/flyweight flyweight.Main ``` ### Proxy (`02-structural/proxy/`) | Post Section | File(s) | |---|---| | The Subject Interface | `DatabaseConnection.java` | | The Real Subject | `RealDatabaseConnection.java` | | Virtual Proxy: Lazy Initialisation | `LazyConnectionProxy.java` | | Logging Proxy: Cross-Cutting Concerns | `LoggingProxy.java` | | Wiring It Together: Proxy Chaining | `Main.java` | Note: the "Dynamic Proxy with java.lang.reflect.Proxy" snippet is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 02-structural/proxy/*.java -d out/proxy java -cp out/proxy proxy.Main ``` ### Chain of Responsibility (`03-behavioral/chain-of-responsibility/`) | Post Section | File(s) | |---|---| | The Problem: Rigid Routing Logic | illustrative only — not part of this repository's runnable example | | Implementation: Support Ticket Escalation — base handler | `SupportHandler.java` | | Implementation: Support Ticket Escalation — the ticket | `SupportTicket.java` | | Each concrete handler checks only its own responsibility — Level 1 & 2 | `Level1Support.java`, `Level2Support.java` | | Level3Support and CriticalIncidentTeam follow exactly the same shape | `Level3Support.java`, `CriticalIncidentTeam.java` | | The chain is assembled in one place | `Main.java` | Run it: ```bash javac 03-behavioral/chain-of-responsibility/*.java -d out/chain java -cp out/chain chain.Main ``` ### Command (`03-behavioral/command/`) | Post Section | File(s) | |---|---| | Step 1 — Command Interface | `Command.java` | | Step 2 — The Receiver (TextEditor) | `TextEditor.java` | | Step 3 — Concrete Commands | `InsertCommand.java`, `DeleteCommand.java` | | Step 4 — The Invoker (CommandHistory) | `CommandHistory.java` | | Demo | `Main.java` | Run it: ```bash javac 03-behavioral/command/*.java -d out/command java -cp out/command command.Main ``` ### Iterator (`03-behavioral/iterator/`) | Post Section | File(s) | |---|---| | Custom Iterator Implementation — the Iterator interface | `BookIterator.java` | | Custom Iterator Implementation — the element type | `Book.java` | | Custom Iterator Implementation — the Aggregate (BookShelf, ForwardIterator, DecadeIterator) | `BookShelf.java` | | Custom Iterator Implementation — wiring it together | `Main.java` | Note: the "How Java's For-Each Loop Uses Iterator" snippet (`Iterable` example) is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/iterator/*.java -d out/iterator java -cp out/iterator iterator.Main ``` ### Mediator (`03-behavioral/mediator/`) | Post Section | File(s) | |---|---| | Implementation: Chat Room — the Mediator interface | `ChatMediator.java` | | Implementation: Chat Room — the Colleague | `User.java` | | Implementation: Chat Room — the Concrete Mediator | `ChatRoom.java` | | Implementation: Chat Room — wiring it together | `Main.java` | Note: the "Mediator in Practice: MVC and Spring Events" snippet (`ApplicationEventPublisher`/`@EventListener` example) is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/mediator/*.java -d out/mediator java -cp out/mediator mediator.Main ``` ### Memento (`03-behavioral/memento/`) | Post Section | File(s) | |---|---| | The Memento: Immutable and Opaque | `EditorMemento.java` | | The Originator (Editor) | `Editor.java` | | The Caretaker (History) | `History.java` | | Wiring it together (Main demo) | `Main.java` | Note: the "Serialization as Memento" snippet (`ObjectOutputStream`/`ObjectInputStream` example) is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/memento/*.java -d out/memento java -cp out/memento memento.Main ``` ### Observer (`03-behavioral/observer/`) | Post Section | File(s) | |---|---| | Implementation: Stock Price Monitoring — the Observer interface | `StockObserver.java` | | Implementation: Stock Price Monitoring — the Subject | `StockMarket.java` | | Implementation: Stock Price Monitoring — AlertObserver | `AlertObserver.java` | | Implementation: Stock Price Monitoring — PortfolioObserver | `PortfolioObserver.java` | | Implementation: Stock Price Monitoring — wiring it together | `Main.java` | Note: the "Push vs Pull Notification Models" pull-model snippet and the "Thread Safety" `CopyOnWriteArrayList` snippet are illustrative only — they are not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/observer/*.java -d out/observer java -cp out/observer observer.Main ``` ### State (`03-behavioral/state/`) | Post Section | File(s) | |---|---| | With State: Traffic Light — the State interface | `TrafficLightState.java` | | With State: Traffic Light — the Context | `TrafficLight.java` | | With State: Traffic Light — RedState | `RedState.java` | | With State: Traffic Light — GreenState | `GreenState.java` | | With State: Traffic Light — YellowState | `YellowState.java` | | With State: Traffic Light — wiring it together | `Main.java` | Note: the "Without State: The if-else Machine" snippet is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/state/*.java -d out/state java -cp out/state state.Main ``` ### Strategy (`03-behavioral/strategy/`) | Post Section | File(s) | |---|---| | Implementation: Pluggable Sorting — the Strategy interface | `SortStrategy.java` | | Implementation: Pluggable Sorting — BubbleSort | `BubbleSort.java` | | Implementation: Pluggable Sorting — MergeSort | `MergeSort.java` | | Implementation: Pluggable Sorting — QuickSort | `QuickSort.java` | | Implementation: Pluggable Sorting — the Context (Sorter) | `Sorter.java` | | Implementation: Pluggable Sorting — wiring it together | `Main.java` | Note: the "Strategy in Java 8+: Lambdas as Strategies" snippet is illustrative only — it is not part of this repository's runnable example. Run it: ```bash javac 03-behavioral/strategy/*.java -d out/strategy java -cp out/strategy strategy.Main ``` ### Template Method (`03-behavioral/template-method/`) | Post Section | File(s) | |---|---| | Implementation: Data Migration Pipeline — the abstract class & template method | `DataMigration.java` | | Implementation: Data Migration Pipeline — CsvMigration | `CsvMigration.java` | | Implementation: Data Migration Pipeline — ApiMigration | `ApiMigration.java` | | Implementation: Data Migration Pipeline — wiring it together | `Main.java` | Run it: ```bash javac 03-behavioral/template-method/*.java -d out/template-method java -cp out/template-method template.Main ``` ### Visitor (`03-behavioral/visitor/`) | Post Section | File(s) | |---|---| | Implementation: Shape Geometry Operations — the Visitor interface | `ShapeVisitor.java` | | Implementation: Shape Geometry Operations — the Element interface | `Shape.java` | | Implementation: Shape Geometry Operations — Circle | `Circle.java` | | Implementation: Shape Geometry Operations — Rectangle | `Rectangle.java` | | Implementation: Shape Geometry Operations — Triangle | `Triangle.java` | | Implementation: Shape Geometry Operations — AreaCalculator | `AreaCalculator.java` | | Implementation: Shape Geometry Operations — PerimeterCalculator | `PerimeterCalculator.java` | | Implementation: Shape Geometry Operations — wiring it together | `Main.java` | Run it: ```bash javac 03-behavioral/visitor/*.java -d out/visitor java -cp out/visitor visitor.Main ``` ## Reference - *Design Patterns: Elements of Reusable Object-Oriented Software* — Gamma, Helm, Johnson, Vlissides - https://refactoring.guru/design-patterns