Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

README.md

Multi-Patterns: Duck Simulator Example

A comprehensive example demonstrating how multiple design patterns work together to create a flexible and maintainable system.

Overview

This Duck Simulator showcases the integration of six different design patterns working in harmony. The application simulates various types of ducks (and geese!) that can quack, be organized into flocks, have their quacks counted, and be observed by interested parties.

Design Patterns Used

1. Strategy Pattern

  • Location: Quackable interface and its implementations
  • Purpose: Defines a family of quacking algorithms and makes them interchangeable
  • Implementation: Each duck type implements the Quackable interface with its own quacking behavior

2. Adapter Pattern

  • Location: GooseAdapter class
  • Purpose: Converts the interface of Goose to work with the Quackable interface
  • Implementation: Wraps a Goose object and translates quack() calls to honk() calls
  • Benefit: Allows geese to participate in the duck simulator without modifying their original implementation

3. Decorator Pattern

  • Location: QuackCounter class
  • Purpose: Adds functionality (counting) to Quackable objects without modifying their code
  • Implementation: Wraps any Quackable and counts each quack while delegating to the wrapped object
  • Benefit: Separates counting logic from duck behavior; can be applied selectively

4. Abstract Factory Pattern

  • Location: AbstractDuckFactory, DuckFactory, AbstractCountingDucks
  • Purpose: Creates families of related objects (decorated vs non-decorated ducks) without specifying concrete classes
  • Implementation:
    • DuckFactory: Creates plain ducks
    • AbstractCountingDucks: Creates ducks pre-wrapped with QuackCounter decorator
  • Benefit: Centralizes object creation and makes it easy to switch between decorated and non-decorated ducks

5. Composite Pattern

  • Location: Flock class
  • Purpose: Treats individual ducks and groups of ducks uniformly
  • Implementation: Flock implements Quackable and contains a collection of Quackable objects
  • Benefit: Allows hierarchical organization of ducks and operations on entire groups

6. Observer Pattern

  • Location: Observer, Observable, QuackObservable, Quackologist
  • Purpose: Notifies interested parties when ducks quack
  • Implementation:
    • QuackObservable: Interface for observable subjects
    • Observable: Helper class managing observer registration and notification
    • Observer: Interface for observers
    • Quackologist: Concrete observer that tracks which ducks quack
  • Benefit: Loose coupling between ducks and observers; multiple observers can track duck behavior

Class Structure

Quackable (interface)
├── extends QuackObservable
│
Duck Implementations:
├── MallardDuck
├── RedheadDuck
├── RubberDuck
├── DuckCall
│
Patterns:
├── GooseAdapter (Adapter Pattern)
├── QuackCounter (Decorator Pattern)
├── Flock (Composite Pattern)
│
Factory:
├── AbstractDuckFactory (Abstract Factory)
├── DuckFactory
├── AbstractCountingDucks
│
Observer:
├── Observer (interface)
├── QuackObservable (interface)
├── Observable (helper class)
├── Quackologist (concrete observer)

How to Compile

From the root directory of the project:

javac -d out MultiPatterns/DuckSimulatorExample/*.java

How to Run

java -cp out MultiPatterns.DuckSimulatorExample.DuckSimulator

Expected Output

Duck Simulator: With Composite -Flocks

Duck Simulator: With Observer

Duck Simulator: Whole Flock Simulation
Quack
Quackologist: Redhead Duck just quacked.
Kwak
Quackologist: Duck Call just quacked.
Squeak
Quackologist: Rubber Duck just quacked.
Honk
Quackologist: Goose pretending to be a Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.

Duck Simulator: Mallard Flock Simulation
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
Quack
Quackologist: Mallard Duck just quacked.
The ducks quacked 11 times

Pros and Cons

Overall Pros

  • Flexibility: Easy to add new duck types without modifying existing code
  • Maintainability: Each pattern has a single responsibility, making the code easier to understand and maintain
  • Extensibility: New behaviors (decorators), observers, or factories can be added without changing core classes
  • Reusability: Patterns can be applied independently or in combination
  • Testability: Individual components can be tested in isolation

Overall Cons

  • Complexity: Multiple patterns increase the number of classes and relationships
  • Learning Curve: Requires understanding of multiple design patterns
  • Overhead: May be over-engineered for simple use cases
  • Performance: Multiple layers of abstraction can have minor performance impacts

Pattern-Specific Analysis

Strategy Pattern (Quackable)

Pros:

  • Open/Closed Principle: New quacking behaviors don't require changing existing code
  • Eliminates conditional logic for different behaviors

Cons:

  • Clients must be aware of different strategies
  • Increases number of objects in the system

Adapter Pattern (GooseAdapter)

Pros:

  • Integrates incompatible interfaces without modifying original classes
  • Promotes code reuse

Cons:

  • Adds an extra layer of indirection
  • Can make code harder to understand if overused

Decorator Pattern (QuackCounter)

Pros:

  • More flexible than inheritance for adding functionality
  • Responsibilities can be added/removed at runtime
  • Follows Single Responsibility Principle

Cons:

  • Can result in many small objects
  • Order of decorators may matter
  • Can be complex to debug wrapped objects

Abstract Factory Pattern

Pros:

  • Ensures consistency in object families
  • Isolates concrete classes from client code
  • Easy to switch between product families

Cons:

  • Adding new product types requires changing all factory classes
  • Increases overall complexity

Composite Pattern (Flock)

Pros:

  • Uniform treatment of individual objects and compositions
  • Simplifies client code
  • Easy to add new component types

Cons:

  • Can make design overly general
  • Type safety can be a concern (all elements must implement same interface)

Observer Pattern

Pros:

  • Loose coupling between subjects and observers
  • Dynamic relationships (observers can be added/removed at runtime)
  • Broadcast communication to multiple observers

Cons:

  • Observers are notified in random order
  • Memory leaks possible if observers aren't properly unregistered
  • Can be hard to debug cascading updates

Key Takeaways

  1. Pattern Synergy: Multiple patterns can work together seamlessly when properly designed
  2. Composition Over Inheritance: The decorator and composite patterns show the power of object composition
  3. Loose Coupling: The observer pattern demonstrates how to achieve loose coupling between components
  4. Flexible Object Creation: The abstract factory pattern centralizes and standardizes object creation
  5. Interface Segregation: Small, focused interfaces (Quackable, Observer) are more flexible than large ones

When to Use This Approach

Good fit for:

  • Systems that need high flexibility and extensibility
  • Applications with multiple variations of similar objects
  • Projects where requirements frequently change
  • Systems requiring runtime behavior modification

Not ideal for:

  • Simple applications with stable requirements
  • Performance-critical systems where every millisecond counts
  • Projects with tight deadlines and limited resources
  • Teams unfamiliar with design patterns

Further Exploration

Try extending the simulator by:

  • Adding new duck types (e.g., DecoyDuck, WildDuck)
  • Creating new decorators (e.g., EchoDecorator that makes ducks quack twice)
  • Implementing additional observers (e.g., QuackLogger, QuackStatistics)
  • Adding a new factory that creates ducks with different decorator combinations