Author: Hassan Bazzoun
A comprehensive, hands-on guide to understanding and implementing the Gang of Four (GoF) Design Patterns in Java. This repository is specifically designed for junior engineers who want to learn design patterns through realistic, easy-to-understand examples.
- What are Design Patterns?
- Why Should You Learn Design Patterns?
- The Three Categories
- Pattern Catalog
- Getting Started
- Running the Examples
- Project Structure
- Contributing
- License
Design patterns are reusable solutions to commonly occurring problems in software design. They represent best practices evolved over time by experienced object-oriented software developers.
Think of design patterns as:
- Templates for solving problems that can be used in many different situations
- A shared vocabulary that helps developers communicate more effectively
- Proven solutions that have been tested and refined over decades
Design patterns are NOT:
- Finished code you can copy and paste
- Algorithms (they don't solve computational problems)
- Language-specific (they're concepts that work across languages)
Design patterns help you write code that is:
- Maintainable - Easier to update and modify
- Scalable - Can grow without becoming messy
- Testable - Easier to write unit tests for
- Readable - Other developers can understand your code faster
When you say "Let's use the Observer pattern here," experienced developers immediately understand what you mean. It's like having a shared language.
These patterns represent decades of collective wisdom from expert developers who faced and solved these problems before you.
Understanding design patterns is often expected in:
- Technical interviews
- Code reviews
- Architecture discussions
- Senior developer positions
Many frameworks and libraries use these patterns:
- Spring Framework uses Singleton, Factory, Proxy
- Android Development uses Observer, Builder, Adapter
- React/Redux uses Observer, Command patterns
- Java Collections uses Iterator, Template Method
The 23 Gang of Four patterns are organized into three categories based on their purpose:
Purpose: Deal with object creation mechanisms
These patterns help you create objects in a way that's appropriate for your situation, making your code more flexible and reusable.
- Singleton - Ensure only one instance exists
- Factory Method - Create objects without specifying exact class
- Abstract Factory - Create families of related objects
- Builder - Construct complex objects step by step
- Prototype - Clone objects instead of creating new ones
Purpose: Deal with object composition and relationships
These patterns help you compose classes and objects into larger structures while keeping these structures flexible and efficient.
- Adapter - Make incompatible interfaces work together
- Bridge - Separate abstraction from implementation
- Composite - Treat individual objects and compositions uniformly
- Decorator - Add responsibilities to objects dynamically
- Facade - Provide simplified interface to complex subsystem
- Proxy - Provide placeholder or surrogate for another object
Purpose: Deal with object interaction and responsibility distribution
These patterns help you define how objects communicate and distribute responsibilities among them.
- Observer - Define one-to-many dependency between objects
- Strategy - Define family of interchangeable algorithms
- Command - Encapsulate requests as objects
- Template Method - Define skeleton of algorithm, let subclasses fill in details
- Iterator - Access elements sequentially without exposing structure
- State - Change object behavior when internal state changes
Note: This tutorial focuses on the most commonly used patterns that junior engineers will encounter in real-world applications.
| Pattern | When to Use | Real-World Example |
|---|---|---|
| Singleton | Need exactly one instance (database connection, logger) | Application configuration manager |
| Factory Method | Don't know exact types of objects needed | Payment processor (Credit Card, PayPal, Crypto) |
| Abstract Factory | Need to create families of related objects | UI toolkit (Windows, Mac, Linux themes) |
| Builder | Object has many optional parameters | Building HTTP requests, SQL queries |
| Prototype | Creating objects is expensive, prefer cloning | Game objects, document templates |
| Pattern | When to Use | Real-World Example |
|---|---|---|
| Adapter | Make incompatible interfaces work together | Legacy code integration, third-party library wrapper |
| Bridge | Avoid explosion of subclasses | Graphics rendering (Shape + Color combinations) |
| Composite | Tree structures of objects | File system, organization hierarchy |
| Decorator | Add responsibilities without modifying code | Coffee orders with add-ons, stream processing |
| Facade | Simplify complex subsystem | Video converter, authentication system |
| Proxy | Control access to objects | Lazy loading, access control, caching |
| Pattern | When to Use | Real-World Example |
|---|---|---|
| Observer | Objects need to react to changes in another object | Event handling, notifications, real-time updates |
| Strategy | Multiple algorithms for same task | Sorting algorithms, payment methods, routing |
| Command | Queue, log, or undo operations | Text editor (undo/redo), transaction system |
| Template Method | Algorithm structure is same, steps vary | Data processing pipeline, test frameworks |
| Iterator | Traverse collection without exposing structure | Playlist navigation, database result sets |
| State | Object behavior changes based on state | Order status, TCP connection, game character |
- Java 17 or higher
- Gradle 8.0 or higher (optional - you can use
gradleor./gradlew) - Your favorite IDE (IntelliJ IDEA, Eclipse, VS Code)
- Clone the repository:
git clone https://github.com/xcodeBn/DesignPatterns.git
cd DesignPatterns- Build the project:
# Option 1: If you have Gradle installed
gradle build
# Option 2: Using the wrapper (uses system Gradle)
./gradlew build- Run tests:
gradle test
# or
./gradlew testNote: Throughout this README, commands are shown using ./gradlew, but you can replace it with gradle if you prefer.
Each design pattern has its own main class that demonstrates realistic usage. You can run them individually:
Creational Patterns:
./gradlew runSingleton
./gradlew runFactory
./gradlew runAbstractFactory
./gradlew runBuilder
./gradlew runPrototypeStructural Patterns:
./gradlew runAdapter
./gradlew runBridge
./gradlew runComposite
./gradlew runDecorator
./gradlew runFacade
./gradlew runProxyBehavioral Patterns:
./gradlew runObserver
./gradlew runStrategy
./gradlew runCommand
./gradlew runTemplateMethod
./gradlew runIterator
./gradlew runState./gradlew runAllPatterns./gradlew tasks --group="Design Patterns"DesignPatterns/
├── src/
│ └── main/
│ └── java/
│ └── com/
│ └── designpatterns/
│ ├── creational/
│ │ ├── singleton/ # Singleton pattern
│ │ ├── factory/ # Factory Method pattern
│ │ ├── abstractfactory/ # Abstract Factory pattern
│ │ ├── builder/ # Builder pattern
│ │ └── prototype/ # Prototype pattern
│ ├── structural/
│ │ ├── adapter/ # Adapter pattern
│ │ ├── bridge/ # Bridge pattern
│ │ ├── composite/ # Composite pattern
│ │ ├── decorator/ # Decorator pattern
│ │ ├── facade/ # Facade pattern
│ │ └── proxy/ # Proxy pattern
│ └── behavioral/
│ ├── observer/ # Observer pattern
│ ├── strategy/ # Strategy pattern
│ ├── command/ # Command pattern
│ ├── templatemethod/ # Template Method pattern
│ ├── iterator/ # Iterator pattern
│ └── state/ # State pattern
├── build.gradle # Gradle build configuration
├── settings.gradle # Gradle settings
└── README.md # This file
Each pattern package contains:
- Pattern implementation - Core classes implementing the pattern
- Demo/Main class - Executable example showing the pattern in action
- README.md - Detailed explanation of the pattern
- Comments - Extensive inline documentation
If you're new to design patterns, here's a recommended learning order:
- Singleton - Simplest pattern, good introduction
- Factory Method - Very common, easy to understand
- Strategy - Practical and widely used
- Observer - Foundation of event-driven programming
- Builder - Helps with complex object creation
- Adapter - Common in integration scenarios
- Decorator - Understanding dynamic behavior
- Command - Powerful for undo/redo functionality
- Abstract Factory - More complex creation pattern
- Composite - Tree structures
- Template Method - Algorithm customization
- State - Complex state management
- Bridge - Advanced abstraction
- Proxy - Access control patterns
- Iterator - Collection traversal
- DO use patterns when they solve a real problem
- DO use patterns to communicate intent
- DON'T force patterns where they don't fit
- DON'T over-engineer simple solutions
- Keep it SIMPLE - The best code is simple code
- Make it READABLE - Code is read more than written
- Make it TESTABLE - Write tests for your patterns
- Follow SOLID principles - They work hand-in-hand with patterns
- Read the code - Don't just read about patterns, study the implementations
- Run the examples - See the patterns in action
- Modify the examples - Break them, fix them, extend them
- Use them in projects - Real practice beats theoretical knowledge
- Teach others - Best way to solidify your understanding
- Pattern Overuse - Not every problem needs a pattern
- Wrong Pattern - Using a pattern that doesn't fit the problem
- Premature Optimization - Start simple, refactor to patterns when needed
- Copy-Paste Without Understanding - Understand WHY the pattern works
- Ignoring Context - Patterns work differently in different contexts
- "Design Patterns: Elements of Reusable Object-Oriented Software" (Gang of Four)
- "Head First Design Patterns" by Freeman & Robson
- "Refactoring to Patterns" by Joshua Kerievsky
- Refactoring.Guru
- SourceMaking
- Java Documentation and Tutorials
Found a bug? Have a suggestion? Want to add more examples?
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) for documenting these patterns
- The software engineering community for decades of pattern refinement
- Junior engineers everywhere who are learning and growing
Hassan Bazzoun
This repository was created to help junior engineers understand design patterns through practical, realistic examples. The goal is to make these powerful concepts accessible and applicable to everyday programming challenges.
Happy Learning! May your code be clean, your patterns be appropriate, and your bugs be few.
If you find this repository helpful, please give it a star and share it with other developers!