0% found this document useful (0 votes)
3 views9 pages

Design Patterns Guide

The GoF Design Patterns Reference Guide outlines 23 design patterns that provide reusable solutions to common software design problems. It categorizes these patterns into Creational, Structural, and Behavioral types, each addressing specific challenges such as object creation, interface mismatches, and communication between objects. Additionally, it includes a selection guide for when to use each pattern and emphasizes clean code principles.

Uploaded by

zayaanlodewyk
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views9 pages

Design Patterns Guide

The GoF Design Patterns Reference Guide outlines 23 design patterns that provide reusable solutions to common software design problems. It categorizes these patterns into Creational, Structural, and Behavioral types, each addressing specific challenges such as object creation, interface mismatches, and communication between objects. Additionally, it includes a selection guide for when to use each pattern and emphasizes clean code principles.

Uploaded by

zayaanlodewyk
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

GoF Design Patterns Reference Guide

Solutions to general problems software developers face

Design patterns are reusable solutions to commonly occurring problems in software design.
They represent best practices and capture experience in a way that others can reuse. This
guide covers the 23 original Gang of Four (GoF) patterns.

Key Concepts
• Von Neumann Architecture: Code and data are the same
• OOP Separation: Code (methods) fixed, Data (members) variable
• Lambdas: Anonymous functions that can capture outside variables
A. Creational Patterns
Patterns for creating objects without having to know all the details
1. Factory Method
Problem Need polymorphic object construction but languages like Java/C++ don't
have virtual constructors

Solution Create a virtual method in parent class that child classes override to return
specific object types

Example Example: ShapeFactory with createShape() method. CircleFactory returns


Circle, SquareFactory returns Square. Client code: Shape s =
[Link](); works with any factory type

When to Use When you need to delegate object creation to subclasses while keeping
client code independent of specific classes

2. Abstract Factory
Problem Need to create families of related objects without specifying their concrete
classes

Solution Provide an interface for creating families of related objects

Example Example: UIFactory creates Button + ScrollBar. WindowsFactory creates


WindowsButton + WindowsScrollBar. MacFactory creates MacButton +
MacScrollBar. Application works with any UI family

When to Use When system should work with multiple product families (Windows/Mac UI,
MySQL/PostgreSQL databases)

3. Builder
Problem Complex objects need step-by-step construction with many optional
parameters

Solution Separate construction process from representation. Builder defines steps,


Director executes them

Example Example: PizzaBuilder with addDough(), addSauce(), addTopping().


MargheritaBuilder and PepperoniBuilder implement differently. Director
calls methods in sequence to build complete pizza

When to Use When creating complex objects with many optional parameters (avoid
telescoping constructors)

4. Prototype
Problem Need to create objects by copying existing instances when creation is
expensive

Solution Clone existing objects instead of creating new ones. Objects implement
clone() method

Example Example: GameCharacter with complex AI state. Instead of reinitializing AI


for each enemy, clone a prototype enemy with pre-configured AI. enemy2
= [Link]();

When to Use When object creation is expensive (complex initialization, database


queries) or when you need object variations

5. Singleton
Problem Ensure only one instance of a class exists and provide global access to it

Solution Private constructor, static instance variable, public getInstance() method

Example Example: [Link]() always returns the same


connection object. [Link]() ensures single log file access point

When to Use Use sparingly! Good for: logging, database connections, hardware
interface access. Bad for: hiding dependencies, making testing difficult
B. Structural Patterns
Patterns for assembling objects into larger structures that are flexible and efficient
1. Adapter
Problem Two interfaces don't match but need to work together

Solution Create wrapper class that translates one interface to another

Example Example: MediaPlayer plays mp3. AdvancedPlayer plays mp4/vlc. Create


AudioAdapter that wraps AdvancedPlayer, implements MediaPlayer
interface. Now MediaPlayer can play all formats

When to Use When integrating third-party libraries, legacy code, or APIs with
incompatible interfaces

2. Bridge
Problem Abstraction and implementation should vary independently (avoid cartesian
product explosion)

Solution Separate abstraction hierarchy from implementation hierarchy using


composition

Example Example: Shape (Circle, Square) and Color (Red, Blue). Without Bridge:
RedCircle, BlueCircle, RedSquare, BlueSquare classes. With Bridge:
Shape has Color, only 4 classes total instead of multiplication

When to Use When you have multiple orthogonal dimensions of variation


(Shape×Color×Border×...)

3. Composite
Problem Need to represent part-whole hierarchies of objects uniformly

Solution Create tree structure where leaf and composite nodes share same
interface

Example Example: FileSystem - File (leaf) and Directory (composite) both implement
FileSystemItem. Directory contains FileSystemItems. Can call getSize() on
file or directory recursively

When to Use When dealing with tree structures: UI components, organization charts, file
systems

4. Decorator
Problem Need to add responsibilities to objects dynamically without altering their
structure

Solution Wrap object with decorator classes that add new behavior while
maintaining same interface

Example Example: Coffee with add-ons. BaseCoffee=$2. MilkDecorator adds $0.50,


SugarDecorator adds $0.25. Can chain: new SugarDecorator(new
MilkDecorator(new BaseCoffee()))

When to Use When you want to add features to objects without inheritance explosion
(alternative to subclassing)
5. Facade
Problem Complex subsystem with many classes is difficult to use

Solution Provide simplified interface that hides complex implementation details

Example Example: HomeTheaterFacade with watchMovie() method that internally:


turns on TV, sets input, dims lights, starts popcorn maker, adjusts sound.
Client just calls watchMovie()

When to Use When you need to simplify complex APIs or provide high-level interface to
complex subsystem

6. Flyweight
Problem Many similar objects consume too much memory due to duplicate data

Solution Share common data between objects, store unique data separately

Example Example: Text editor with millions of characters. Instead of Character


object per letter, share CharacterFlyweight (font, size) and store position
separately. 'AAA' uses one 'A' flyweight three times

When to Use When you have huge number of similar objects (particles in games,
characters in documents)

7. Proxy
Problem Need to control access to an object or defer its creation/initialization

Solution Create surrogate object that controls access to the real object

Example Example: ImageProxy for large images. Shows placeholder immediately,


loads real image in background. DatabaseProxy adds connection pooling
and caching before forwarding to real database

When to Use Virtual proxy (lazy loading), Protection proxy (access control), Remote
proxy (network calls), Cache proxy
C. Behavioral Patterns
Patterns for communication between objects and assignment of responsibilities
1. Chain of Responsibility
Problem Request needs to be processed by one of several handlers, but which one
isn't known in advance

Solution Chain handlers together. Each decides to process or pass to next handler

Example Example: Customer support system. Level1Support handles basic issues,


forwards complex to Level2Support, which forwards critical to
Level3Support. Request flows until handled

When to Use Event handling in UI, middleware in web servers, approval workflows

2. Command
Problem Need to decouple sender from receiver, queue operations, support undo

Solution Encapsulate request as an object with execute() method

Example Example: Text editor - CutCommand, CopyCommand, PasteCommand all


implement Command interface. Can store in history stack for undo/redo.
Toolbar buttons just call [Link]()

When to Use Undo/redo functionality, macro recording, queuing operations, remote


procedure calls

3. Iterator
Problem Need to traverse collection without exposing internal structure

Solution Provide interface with hasNext() and next() methods to traverse elements

Example Example: BookCollection with inner BookIterator. Client uses


[Link]() and [Link]() without knowing if books stored in
array, list, or tree

When to Use Built into modern languages (for-in loops). Custom traversal orders,
multiple simultaneous iterations

4. Mediator
Problem Many objects need to communicate, creating complex dependencies

Solution Central mediator handles all communication between objects

Example Example: ChatRoom mediator. Users don't send messages directly to each
other. They send to ChatRoom, which distributes to relevant users. Users
only know ChatRoom, not each other

When to Use GUI components interaction, air traffic control, chat applications

5. Memento
Problem Need to save/restore object state without violating encapsulation

Solution Object creates memento containing snapshot of state. Caretaker stores


mementos
Example Example: Game save system. GameState creates GameMemento with
level, score, position. SaveManager (caretaker) stores mementos. Can
restore any previous save without accessing private GameState fields

When to Use Undo mechanisms, database transactions, game save systems

6. Observer
Problem Multiple objects need notification when another object changes state

Solution Subject maintains list of observers, notifies them of state changes

Example Example: Stock price monitor. Stock is subject, multiple StockDisplay


observers. When [Link](100) called, all displays automatically
update via update() callback

When to Use Model-View patterns, event handling, distributed event systems

7. State
Problem Object behavior changes based on internal state (avoiding huge switch
statements)

Solution Create state classes for each state. Object delegates to current state
object

Example Example: Music player with PlayingState, PausedState, StoppedState.


[Link]() delegates to [Link](). Each state
handles same action differently

When to Use State machines, game character AI, UI components with modes

8. Strategy
Problem Multiple algorithms exist for a task, need to select at runtime

Solution Define family of algorithms, encapsulate each, make them interchangeable

Example Example: PaymentProcessor with strategies: CreditCardPayment,


PayPalPayment, BitcoinPayment. Shopping cart uses
[Link](amount) regardless of payment method selected

When to Use Sorting algorithms, compression algorithms, validation rules, pricing


calculations

9. Template Method
Problem Algorithm structure is same but some steps vary between implementations

Solution Define skeleton in base class, subclasses override specific steps

Example Example: DataMiner with steps: openFile(), extractData(), parseData(),


analyzeData(), closeFile(). PDFMiner and CSVMiner override extractData()
and parseData() differently

When to Use Framework hooks, data processing pipelines, game AI turn sequences

10. Visitor
Problem Need to add operations to class hierarchy without modifying classes
Solution Operations become visitor objects that visit elements of hierarchy

Example Example: Document with Paragraph, Image, Table elements. Instead of


adding export methods to each, create PDFExportVisitor,
HTMLExportVisitor. Elements accept(visitor), visitor handles specifics

When to Use Compilers (AST traversal), document converters, adding operations to


stable class hierarchies
Design Pattern Selection Guide
When to Use Which Pattern
• Object Creation Issues → Creational Patterns (Factory, Builder, Prototype)
• Interface Mismatch → Adapter or Facade
• Add Features Dynamically → Decorator or Proxy
• Algorithm Variations → Strategy or Template Method
• State-Dependent Behavior → State Pattern
• One-to-Many Updates → Observer Pattern
• Undo/History → Command or Memento
• Tree Structures → Composite Pattern
• Memory Optimization → Flyweight Pattern

Clean Code Principles


• DRY: Don't Repeat Yourself
• Single Responsibility: One class, one purpose
• Meaningful Names: Code is for humans first
• No Magic Constants: Name your constants
• Composition over Inheritance: Prefer HAS-A over IS-A

You might also like