Skip to content

xcodeBn/DesignPatternsv4

Repository files navigation

Design Patterns Tutorial for Junior Engineers

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.

Table of Contents

What are Design Patterns?

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)

Why Should You Learn Design Patterns?

1. Write Better Code

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

2. Communicate Better

When you say "Let's use the Observer pattern here," experienced developers immediately understand what you mean. It's like having a shared language.

3. Learn from Experts

These patterns represent decades of collective wisdom from expert developers who faced and solved these problems before you.

4. Career Growth

Understanding design patterns is often expected in:

  • Technical interviews
  • Code reviews
  • Architecture discussions
  • Senior developer positions

5. Understand Existing Code

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 Three Categories

The 23 Gang of Four patterns are organized into three categories based on their purpose:

Creational Patterns (5)

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

Structural Patterns (7)

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

Behavioral Patterns (11)

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 Catalog

Creational Patterns

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

Structural Patterns

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

Behavioral Patterns

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

Getting Started

Prerequisites

  • Java 17 or higher
  • Gradle 8.0 or higher (optional - you can use gradle or ./gradlew)
  • Your favorite IDE (IntelliJ IDEA, Eclipse, VS Code)

Installation

  1. Clone the repository:
git clone https://github.com/xcodeBn/DesignPatterns.git
cd DesignPatterns
  1. Build the project:
# Option 1: If you have Gradle installed
gradle build

# Option 2: Using the wrapper (uses system Gradle)
./gradlew build
  1. Run tests:
gradle test
# or
./gradlew test

Note: Throughout this README, commands are shown using ./gradlew, but you can replace it with gradle if you prefer.

Running the Examples

Each design pattern has its own main class that demonstrates realistic usage. You can run them individually:

Run Individual Patterns

Creational Patterns:

./gradlew runSingleton
./gradlew runFactory
./gradlew runAbstractFactory
./gradlew runBuilder
./gradlew runPrototype

Structural Patterns:

./gradlew runAdapter
./gradlew runBridge
./gradlew runComposite
./gradlew runDecorator
./gradlew runFacade
./gradlew runProxy

Behavioral Patterns:

./gradlew runObserver
./gradlew runStrategy
./gradlew runCommand
./gradlew runTemplateMethod
./gradlew runIterator
./gradlew runState

Run All Patterns

./gradlew runAllPatterns

List All Available Tasks

./gradlew tasks --group="Design Patterns"

Project Structure

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

Learning Path

If you're new to design patterns, here's a recommended learning order:

Beginner (Start Here)

  1. Singleton - Simplest pattern, good introduction
  2. Factory Method - Very common, easy to understand
  3. Strategy - Practical and widely used
  4. Observer - Foundation of event-driven programming

Intermediate

  1. Builder - Helps with complex object creation
  2. Adapter - Common in integration scenarios
  3. Decorator - Understanding dynamic behavior
  4. Command - Powerful for undo/redo functionality

Advanced

  1. Abstract Factory - More complex creation pattern
  2. Composite - Tree structures
  3. Template Method - Algorithm customization
  4. State - Complex state management
  5. Bridge - Advanced abstraction
  6. Proxy - Access control patterns
  7. Iterator - Collection traversal

Best Practices

When to Use Patterns

  • 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

Code Quality

  • 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

Learning Tips

  1. Read the code - Don't just read about patterns, study the implementations
  2. Run the examples - See the patterns in action
  3. Modify the examples - Break them, fix them, extend them
  4. Use them in projects - Real practice beats theoretical knowledge
  5. Teach others - Best way to solidify your understanding

Common Pitfalls to Avoid

  1. Pattern Overuse - Not every problem needs a pattern
  2. Wrong Pattern - Using a pattern that doesn't fit the problem
  3. Premature Optimization - Start simple, refactor to patterns when needed
  4. Copy-Paste Without Understanding - Understand WHY the pattern works
  5. Ignoring Context - Patterns work differently in different contexts

Resources for Further Learning

Books

  • "Design Patterns: Elements of Reusable Object-Oriented Software" (Gang of Four)
  • "Head First Design Patterns" by Freeman & Robson
  • "Refactoring to Patterns" by Joshua Kerievsky

Online

Contributing

Found a bug? Have a suggestion? Want to add more examples?

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • 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

About the Author

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!