0% found this document useful (0 votes)
5 views

Software Design Review

The CS3620 Exam Review document provides an overview of design patterns, principles, and object-oriented design concepts. It covers various design patterns including Strategy, Observer, Decorator, Factory, and Singleton, along with their motivations, implementations, and real-world applications. Additionally, it discusses key design principles such as SOLID and UML basics, aimed at enhancing understanding of software design.

Uploaded by

eccovc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Software Design Review

The CS3620 Exam Review document provides an overview of design patterns, principles, and object-oriented design concepts. It covers various design patterns including Strategy, Observer, Decorator, Factory, and Singleton, along with their motivations, implementations, and real-world applications. Additionally, it discusses key design principles such as SOLID and UML basics, aimed at enhancing understanding of software design.

Uploaded by

eccovc
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

CS3620 Exam Review

Contents
1 Design Patterns Overview 3
1.1 Course Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Why Use Design Principles & Patterns? . . . . . . . . . . . . . . . . . . . . . 3
1.1.2 OOP Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3 Object-Oriented Design Principles . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.4 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.5 Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.6 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.7 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Design Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.2 SOLID Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2.3 Other Design Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.4 Additional Design Principles . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.5 What is a Class? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2.6 Grady Booch’s Quality Metrics . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.2.7 UML Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2 Creational Patterns 8
2.1 Strategy Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.3 Problems with Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.4 Alternatives Considered . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.5 Solution: Strategy Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.6 Key Design Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.7 Implementation Details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.8 Duck Simulation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.9 Composition vs Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.1.10 Real-World Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.2 Lecture 04: Observer Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.2 Weather Monitoring System Example . . . . . . . . . . . . . . . . . . . . . . 11
2.2.3 Initial Design Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.4 Observer Pattern Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.2.5 Implementation Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.2.6 Push vs Pull Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

1
2.2.7 Java Built-in Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.2.8 Real-World Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3 Lecture 05: Decorator Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2.3.3 Example: Starbuzz Coffee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.4 How Decorators Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.5 Key Participants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.6 Decorator vs Strategy Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.3.7 Real-World Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.4 Lecture 06: Factory Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.2 Types of Factory Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.3 Simple Factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.4 Factory Method Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.5 Abstract Factory Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.6 Key Benefits Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.4.7 Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5 Lecture 07: Singleton Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.3 Implementation Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.4 Singleton vs Static Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.5 Multithreading Concerns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.5.6 Singleton Variations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.5.7 Drawbacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3 Behavioural Patterns 18
3.1 Lecture 08: Command Pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.2 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.3 Example: Smart Home Remote Control . . . . . . . . . . . . . . . . . . . . . 18
3.1.4 Key Participants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1.5 Benefits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1.6 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Lecture 09: Adapter & Facade Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.2 Adapter Pattern Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.3 Adapter Pattern Participants . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.4 Adapter Use Cases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.5 Facade Pattern Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.6 Facade Pattern Participants . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.7 Home Theater Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.8 Adapter vs Facade Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1 Design Patterns Overview

1.1 Course Introduction

This course focuses on Software Design, particularly Object-Oriented (OO) Design. It covers
three main areas:
1. OO Design Principles - Guidelines for creating better software
2. Design Patterns - Reusable solutions for common software problems
3. Software Architecture - High-level organization of software systems

1.1.1 Why Use Design Principles & Patterns?

Designing reusable software is difficult:


• Identifying the right objects
• Structuring them properly in classes
• Managing relationships and inheritance
Expert designers don’t reinvent the wheel:
• They reuse proven solutions (design patterns)
• Patterns make software more flexible, elegant, and reusable

1.1.2 OOP Review


• Encapsulation – Hiding implementation details
• Abstraction – Focusing on essential properties
• Polymorphism – Using a common interface for different types
• Inheritance – Creating new classes from existing ones

1.1.3 Object-Oriented Design Principles


• Modularity: Dividing software into independent components
• Encapsulation: Hiding internal details from the outside world
• Abstraction: Exposing only necessary details
• Inheritance: Reusing code through hierarchical relationships

1.1.4 Encapsulation
• Restricts access to internal object details
• Reduces dependencies between components
• Example: Make fields private and expose them through public methods

1.1.5 Abstraction
• Hides complexity by providing a simplified interface
• Abstract Classes vs. Interfaces:
– Interface: Defines behavior but no implementation

3
– Abstract Class: Can define some default behaviors

1.1.6 Inheritance
• ”Is-a” relationship: One class inherits behavior from another
• Used for code reuse, but can lead to tight coupling
• Benefits:
– Code reuse through hierarchical relationships
– Establishes type relationships
• Drawbacks:
– Can create rigid hierarchies
– May violate LSP if not careful
– Increases coupling between classes

1.1.7 Polymorphism
• Same interface, different implementations
• Types of Polymorphism:
– Runtime (Dynamic) - Method overriding
– Compile-time (Static) - Method overloading
• Benefits:
– Flexibility in design
– Supports ”programming to interfaces”
– Enables loose coupling

1.2 Design Principles

1.2.1 Overview

Object-Oriented (OO) Design Principles provide guidelines for writing clean, maintainable,
and flexible software.
• Design Patterns are built on these principles
• Without understanding these principles, design patterns may not be fully understood

1.2.2 SOLID Principles

Mnemonic introduced by Robert Martin:


1. Single Responsibility Principle (SRP)
• A class should have only one reason to change
• Every software module should have a single responsibility
• Example: A module that compiles and prints a report should be separated into:
– One class for content generation
– Another class for formatting
2. Open/Closed Principle (OCP)
• Software entities should be open for extension, but closed for modification
• A class should be extendable without modifying its source code

4
• Example: Instead of modifying a class every time a new shape is introduced, use an
abstract shape interface
• New shapes can be added by implementing the interface, without changing existing code
3. Liskov Substitution Principle (LSP)
• Subtypes must be replaceable with their base types without breaking the program
• A derived class should not alter the expected behavior of its base class
• Example Problem: A Square subclass of Rectangle violates LSP
• Setting one side of a square affects both width and height, breaking expectations
• Solution:
– Make the Rectangle immutable
– Remove the inheritance relationship
– Define Square separately
4. Interface Segregation Principle (ISP)
• Prefer many small interfaces over a single large interface
• A class should not be forced to implement methods it does not use
• Example: If a Worker interface includes takeBreak(), it’s inappropriate for robot work-
ers
• Solution: Split into smaller interfaces (Workable, Breakable)
5. Dependency Inversion Principle (DIP)
• High-level modules should not depend on low-level modules
• Both should depend on abstractions
• Abstractions should not depend on details
• Details should depend on abstractions
• Example: A Copy module should depend on abstract interfaces:
– Reader interface instead of KeyboardReader
– Writer interface instead of PrinterWriter

1.2.3 Other Design Principles


1. Don’t Repeat Yourself (DRY)
• Avoid duplicate code
• Use abstraction to centralize common functionality
• Helps maintainability by reducing redundancy
• Example: Extract common validation logic into a shared utility class
2. Encapsulate What Varies
• Identify the parts of the system that change and separate them
• Example: Use abstract file handler for multiple formats
• Benefits:
– Reduces impact of changes
– Makes code more flexible
– Easier to maintain and extend
3. Strive for Loose Coupling
• Minimize dependencies between objects
• Example: Observer Pattern allows loose communication
• Benefits:
– Easier to modify components independently
– Better reusability
– Easier to test

5
4. Principle of Least Knowledge (Law of Demeter)
• Objects should interact only with closely related objects
• Only talk to your immediate friends
• Avoid method chaining: a.getB().getC().doSomething()
• Instead delegate through appropriate objects
• Benefits:
– Reduces dependencies
– Makes code more maintainable
– Easier to modify individual components
5. Hollywood Principle
• ”Don’t call us, we’ll call you”
• Low-level components can hook into high-level components
• But high-level components control when to call them
• Examples:
– Template Method Pattern
– Observer Pattern
– Dependency Injection frameworks

1.2.4 Additional Design Principles

Favor Composition Over Inheritance


• Composition (”has-a”) is more flexible than inheritance (”is-a”)
• Inheritance creates rigid hierarchy, while composition allows greater modularity
• Example: Strategy Pattern allows interchangeable behavior without modifying existing
code
• Benefits:
– More flexible design
– Easier to change behavior at runtime
– Reduces coupling between classes
Program to Interfaces
• Use interface types instead of concrete classes
• Promotes flexibility and decouples implementation from usage
• Example: Instead of specific list type, use generic collection interface
• Benefits:
– More flexible code
– Easier to change implementations
– Better testing support

1.2.5 What is a Class?


• A blueprint for objects
• Defines attributes (data) and methods (behavior)
• Core building block of object-oriented design

6
1.2.6 Grady Booch’s Quality Metrics
• Coupling:
– Minimize interdependencies between classes
– Fewer connections mean easier maintenance
– Changes in one class affect fewer other classes
• Cohesion:
– Keep related data and behaviors together
– Each class should have a single, well-defined purpose
– Methods should work together to serve class’s purpose
• Sufficiency:
– Capture enough details to be useful
– Include all necessary operations
– Balance between completeness and simplicity
• Completeness:
– Include all necessary behavior
– Public interface should provide all needed functionality
– No missing operations that clients need
• Primitiveness:
– Avoid unnecessary methods
– Each operation should be atomic and fundamental
– Don’t include operations that can be composed from others

1.2.7 UML Basics


• Unified Modeling Language (UML) helps visualize software design
• Provides standard way to model software systems
• Essential for communicating design decisions
Key UML Diagrams:
• Class Diagram:
– Shows relationships between classes
– Displays attributes and methods
– Represents class structure
• Sequence Diagram:
– Describes interactions over time
– Shows message flow between objects
– Represents dynamic behavior
• Use Case Diagram:
– Represents system functionality
– Shows actor interactions
– Captures requirements
Common UML Relationships:

7
Figure 1: UML Relationship Types

Type Description
Association One class uses another (→)
Inheritance Subclass extends superclass (▷)
Realization/Implementation Class implements interface (99K ▷)
Dependency Loosely defined relationship (99K)
Aggregation Weak ”has-a” relationship (♢)
Composition Strong ”has-a” relationship (♦)

2 Creational Patterns

2.1 Strategy Pattern

2.1.1 Overview

The Strategy Pattern:


• Allows algorithm’s behavior to be selected at runtime
• Used when different algorithms are appropriate at different times
• Enables flexible and reusable behavior definitions

8
2.1.2 Motivation

Example: SimUDuck - a duck pond simulation game


• Initially designed using inheritance:
– A Duck superclass contains common behavior
– Subclasses like MallardDuck and RubberDuck inherit from Duck

2.1.3 Problems with Inheritance


• Adding new behavior (e.g., fly()) to superclass means all ducks will have it
• Some ducks shouldn’t fly (e.g., rubber ducks, decoy ducks)
• Leads to code duplication and maintenance issues
• Behaviors must be overridden in many subclasses

2.1.4 Alternatives Considered

Using Interfaces:
• Introduced Flyable and Quackable interfaces
• Problems:
– Each class must provide its own fly() and quack() method
– No code reuse – changes must be updated in multiple places
– Doesn’t allow for easy runtime behavior changes
Java 8 Default Methods:
• Provides reusable implementations in interfaces
• Helps prevent breaking existing implementations
• Limitations:
– Cannot maintain object state
– Unsuitable for strategy-based behaviors

2.1.5 Solution: Strategy Pattern


• Encapsulate behaviors for easy extension/change
• Separate varying parts from stable parts:
– Varying: flying, quacking
– Stable: swimming, displaying

2.1.6 Key Design Principle


• Program to an abstraction, not an implementation
• Use interfaces/abstract classes for behaviors
• Avoid hardcoded methods

2.1.7 Implementation Details


• Interfaces:

9
– FlyBehavior
– QuackBehavior
• Behavior Classes:
– FlyWithWings
– FlyNoWay
– Quack
– Squeak
– MuteQuack
• Delegate behaviors to strategy objects instead of defining in Duck

2.1.8 Duck Simulation Example


• Duck class holds references to behaviors:

public abstract class Duck {


FlyBehavior flyBehavior;
QuackBehavior quackBehavior;

public void performFly() {


flyBehavior.fly();
}

public void setFlyBehavior(FlyBehavior fb) {


flyBehavior = fb;
}
}

• Dynamic behavior changes:

Duck model = new ModelDuck();


model.setFlyBehavior(new FlyRocketPowered());

2.1.9 Composition vs Inheritance


• Use composition (”has-a”) over inheritance (”is-a”)
• Benefits:
– Dynamic behavior changes
– Behavior sharing across objects
– More flexible design

2.1.10 Real-World Applications


• Sorting:
– Different algorithms (quicksort, mergesort)
– Choose based on data characteristics
• Games:
– Character movement strategies

10
– Different behaviors for NPCs
• Data Storage:
– Database vs cloud vs local file
– Strategy selected based on requirements

2.2 Lecture 04: Observer Pattern

2.2.1 Overview

The Observer Pattern:


• Establishes one-to-many dependency between objects
• Subject notifies observers of state changes automatically
• Provides loose coupling between components

2.2.2 Weather Monitoring System Example

Requirements:
• Weather Station monitors:
– Humidity
– Temperature
– Barometric pressure
• Display types:
– Current Conditions Display
– Weather Statistics Display
– Forecast Display
• Support for future extensions

2.2.3 Initial Design Problems


• WeatherData calls update() on each display
• Tight coupling to display implementations
• Modification required for adding/removing displays

2.2.4 Observer Pattern Solution

Key Participants:
1. Subject (Observable):
• Maintains observer list
• Notifies on data changes
• Methods:
registerObserver(Observer o)
removeObserver(Observer o)
notifyObservers()

2. Observers:

11
• Register with subject
• Receive automatic updates
• Method: update(data)

2.2.5 Implementation Example

public interface Subject {


void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}

public interface Observer {


void update(float temp, float humidity,
float pressure);
}

public class WeatherData implements Subject {


private List<Observer> observers;
private float temperature;
private float humidity;

public void measurementsChanged() {


notifyObservers();
}

public void setMeasurements(float temp,


float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
measurementsChanged();
}
}

2.2.6 Push vs Pull Models

Push Model (Eager):


• Subject sends all data to observers
• Simple but may send unnecessary data
• Example:

update(temp, humidity, pressure)

Pull Model (Lazy):


• Observers request needed data
• More efficient for large datasets

12
• Example:

update()
float temp = subject.getTemperature();

2.2.7 Java Built-in Support


• Observable class and Observer interface
• Key methods:
– setChanged() - signals state change
– notifyObservers() - updates observers
• Limitations:
– Observable is a class, not interface
– Multiple inheritance issues
– Protected setChanged() method

2.2.8 Real-World Applications


• MVC Pattern:
– Model (Subject) notifies Views (Observers)
– Views update when data changes
• GUI Systems:
– Button click events
– Window state changes
• Event Handling:
– Event listeners
– Callback mechanisms

2.3 Lecture 05: Decorator Pattern

2.3.1 Overview

The Decorator Pattern:


• Is a structural pattern for adding behavior dynamically
• Provides alternative to subclassing for extending functionality
• Follows Open-Closed Principle
• Uses composition over inheritance

2.3.2 Motivation

Consider a logging system that needs added functionality:


• Encryption
• Compression
• Using inheritance leads to rigid and inflexible class hierarchies

13
2.3.3 Example: Starbuzz Coffee

Problem: Managing beverages and condiments


• Initial attempts:
– Creating subclasses for every combination → Too many classes!
– Using boolean flags for condiments → Violates Open-Closed Principle

2.3.4 How Decorators Work


• Decorator has same supertype as decorated object
• Delegates work to wrapped object while adding behavior
• Multiple decorators can be combined at runtime

2.3.5 Key Participants

Role Description
Component Defines interface for objects that can be decorated
ConcreteComponent Base object to which decorators are added
Decorator Maintains reference to Component and matches interface
ConcreteDecorator Extends functionality by modifying/adding behavior

2.3.6 Decorator vs Strategy Pattern

Decorator Strategy
Changes external behavior Changes internal logic
Stacks multiple behaviors Replaces entire behaviors

2.3.7 Real-World Examples


• Java I/O:
– BufferedInputStream
– GzipInputStream
– ObjectInputStream
• GUI Toolkits:
– Adding scrollbars
– Adding borders
– Other UI elements
• Security Wrappers:
– Authentication layers
– Encryption layers

14
2.4 Lecture 06: Factory Patterns

2.4.1 Overview

Factory Patterns:
• Handle object creation while hiding instantiation logic
• Decouple object creation from application logic

2.4.2 Types of Factory Patterns


1. Simple Factory (not official pattern)
2. Factory Method Pattern
3. Abstract Factory Pattern

2.4.3 Simple Factory


• Encapsulates creation in factory class
• Pros:
– Reduces duplication of creation logic
– Centralizes object creation
• Cons:
– Needs modification for new types

2.4.4 Factory Method Pattern


• Uses inheritance for object creation
• Subclasses implement create method
• Example: Pizza Store:
– Abstract PizzaStore
– NYPizzaStore, ChicagoPizzaStore implement createPizza()

2.4.5 Abstract Factory Pattern


• Creates families of related objects
• Example: Different pizza styles (NY, Chicago, California)
• Decouples creation from implementations

2.4.6 Key Benefits Comparison

Feature Factory Method Abstract Factory


Uses Inheritance Yes No
Uses Composition No Yes
Supports Product Families No Yes
Extensible Yes Yes

15
2.4.7 Use Cases
• Database Connections:
– Different drivers (MySQL, PostgreSQL)
• UI Frameworks:
– Platform-specific UI elements
• Dependency Injection:
– Decoupling instantiation from business logic

2.5 Lecture 07: Singleton Pattern

2.5.1 Overview

The Singleton Pattern:


• Ensures class has only one instance
• Provides global access point
• Controls shared resources

2.5.2 Motivation

Applications requiring one-of-a-kind objects:


• Logger: Single log file access
• Configuration Manager: Single source of settings
• Database Connection Manager: Connection pooling
• Thread Pool Manager: Worker thread control

2.5.3 Implementation Strategy


• Private constructor prevents external instantiation
• Static getInstance() method returns single instance
• Lazy initialization creates instance when needed

2.5.4 Singleton vs Static Class

Singleton Static Class


Can be instantiated Cannot be instantiated
Supports polymorphism Cannot extend classes
Uses lazy loading Loaded immediately
Allows object state Only class-level state

2.5.5 Multithreading Concerns


• Multiple threads may create multiple instances
• Solutions:
– Synchronized getInstance() (performance impact)

16
– Eager initialization (startup creation)
– Double-checked locking (balanced approach)
– Volatile keyword (memory visibility)

2.5.6 Singleton Variations


1. Lazy Initialization:

private static Singleton instance;


public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

2. Eager Initialization:

private static final Singleton instance


= new Singleton();

3. Thread-Safe Singleton:

public static synchronized Singleton


getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

4. Double-Checked Locking:

private volatile static Singleton instance;


public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}

5. Enum Singleton:

17
public enum Singleton {
INSTANCE;
public void doWork() {
// singleton behavior
}
}

2.5.7 Drawbacks
• Global State Issues:
– Similar to global variables
– Makes testing harder
• Hidden Dependencies:
– Complicates dependency injection
• Threading & Serialization:
– Requires special handling
– Can be complex to implement correctly

3 Behavioural Patterns

3.1 Lecture 08: Command Pattern

3.1.1 Overview

The Command Pattern:


• Encapsulates a request as an object
• Enables:
– Undo/Redo functionality
– Queueing requests
– Decoupling request senders and receivers

3.1.2 Motivation
• Inspired by macros - recording actions for later execution
• Common in:
– GUIs
– Remote controls
– Job queues
– Multi-level undo systems

3.1.3 Example: Smart Home Remote Control


• Remote controls multiple devices:
– Lights
– TVs

18
– AC units
• Uses Command objects instead of hardcoded logic
• Commands encapsulate device actions
• Remote only calls execute() without device knowledge

3.1.4 Key Participants

Role Description
Command Interface for executing operations
ConcreteCommand Implements execute() for receiver operations
Receiver Knows how to perform operations
Invoker Stores and triggers command execution
Client Creates commands and assigns to invoker

3.1.5 Benefits
• Encapsulates requests as objects
• Decouples sender from receiver
• Supports undo/redo functionality
• Enables command logging and queuing

3.1.6 Extensions
• Undo Commands:
– Requires undo() method
– Stores state for reversal
• Macro Commands:
– Multiple commands in sequence
– Single invocation executes all
• Lambda Commands:
– Java 8+ lambda expressions
– Replace concrete command classes

3.2 Lecture 09: Adapter & Facade Patterns

3.2.1 Overview
• Adapter Pattern: Converts incompatible interfaces
• Facade Pattern: Simplifies complex system interfaces

3.2.2 Adapter Pattern Motivation


• Handles incompatible interfaces between classes
• Example: Text rendering library in graphics editor
• Adapts existing code without modification

19
3.2.3 Adapter Pattern Participants

Role Description
Target Expected interface
Adapter Converts Adaptee to Target
Adaptee Existing incompatible class
Client Uses Target interface

3.2.4 Adapter Use Cases


• UI Components:
– Adapting third-party controls
– Making widgets work together
• Legacy Code Integration:
– Wrapping old interfaces
– Maintaining compatibility
• Database Wrappers:
– Different database drivers
– Unified access interface

3.2.5 Facade Pattern Motivation


• Simplifies access to complex subsystems
• Reduces dependencies between clients and implementation
• Provides high-level interface

3.2.6 Facade Pattern Participants

Role Description
Facade Provides simple API to subsystem
Subsystem Handles actual complex logic
Client Uses Facade instead of direct interaction

3.2.7 Home Theater Example

Without Facade:

amplifier.on();
dvdPlayer.play();
projector.setMode(Widescreen);
// Complex for users

With Facade:

homeTheater.watchMovie();
// Hides unnecessary details

20
3.2.8 Adapter vs Facade Comparison

Aspect Adapter Facade


Purpose Converts interface Simplifies interface
Changes Behavior No No
Multiple Objects No Yes

3.2.9 Summary
• Adapter:
– Makes incompatible interfaces work together
– Maintains existing code
– Enables reuse of legacy components
• Facade:
– Simplifies complex subsystems
– Reduces dependencies
– Improves maintainability

21

You might also like