M6 — Composition and Structural Patterns

SENG 365 — Software Engineering

Neil Ernst

University of Victoria

2026-07-24

Learning Objectives

Learning Objectives

Reading: Robillard, 3rd ed. — Ch. 6, Composition (pp. 125–156).

  • When and how composition makes sense
  • Composite, Decorator, and Command design patterns
  • Sequence diagrams and the Law of Demeter

Composition vs. “is-a”

  • Interfaces and classes use the subtype (“is-a”) relationship. Give an example.
  • Composition is the “part-of” relationship (an arm is part of a body).
  • Important for assembling large wholes from smaller pieces.
  • A Team aggregates Players; the team’s points are the sum of player points.

Composite

Composite Pattern

Groups of objects behave like single objects.

Think of folders vs. files: ls doesn’t differentiate, except folders contain children.

  • Client code depends on the component type, not concrete implementations.
  • Support open-ended configurations via object composition, not class definition.

Composite: Movie Theatre

  • Client — Program
  • Primitive — Movie, DoubleBill, Null
  • Interface — Show
  • Composite — CompositeShow

Name: Composite · Intent: treat groups of objects as a single object.

The Null Object Pattern

  • Traversing a Composite, some objects may be empty (a folder with no children).
  • Instead of checking for null everywhere, a null object does a no-op.
  • Removes a class of special-case checks.

Decorator

Design Problem

A point-of-sale system for a coffee shop. Basic beverages, but customers customize (milk, syrup, …).

  • A class per drink → combinatorial explosion.
  • A single MultiDrink with switch statements → a God class with multiple responsibilities.

Decorator Pattern

Name: Decorator · Intent: attach additional responsibilities to an object dynamically.

Decorator Explained

Decorator Concepts

  • Decorators are of the primitive type → enables chaining.
  • Additive: a decorator cannot remove another’s contribution.
  • Implement the primitive type and delegate the method to the decorated object (cost(), draw()).
  • Original object identity is lost.
  • Common in GUI toolkits.
BufferedInputStream bis =
  new BufferedInputStream(new FileInputStream(new File("a.txt")));

Copying and Prototype

Object Copying

Prototype Pattern

Change the default class at runtime where the type can’t be known ahead of time.

  • Create the prototypical class (e.g. Deck), support dynamic switches (setPrototype).
  • Downside: the specific type isn’t guaranteed → clients must depend on the interface (good practice anyway).

Command and Demeter

Sequence Diagrams

  • Left to students to read up on.
  • Focus: how they capture the flow of control.
  • Video: example of a REST query and authentication.

Command Pattern

  • Commands typically map to method calls (think of a menu item).
  • We may want to treat a Command holistically — to support undo, GUI mapping, macros.
  • Make function calls (e.g. draw()) their own objects.
  • Design choices: how to access the target; data flow; pre/post conditions; storing command history.

The “Law” of Demeter

  • AKA the principle of least knowledge — ensure loose coupling.
  • aFoundations.getPile(FIRST).getCards().add(pCard); requires too much knowledge of other classes.
  • Objects should rely only on: the implicit parameter; its fields; method arguments; new objects created within; globally available objects.
  • Use only one “dot”; add helper methods (at the expense of clutter).

In-Class Activities

Day 1

  • Group discussion

Day 2

  • Jackson demo for parsing JSON
  • Configuring GitHub Actions

Day 3

  • Office hours