Lecture recording here.
Lab recording here.
We will look at some more structural patterns, the decorator and composite patterns. The Decorator pattern allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The Composite pattern composes objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.
| The Decorator Pattern | Decorator Design Pattern |
| The Decorator Pattern Explained and Implemented in Java | |
| The Composite Pattern | Composite Design Pattern |
| The Composite Pattern Explained and Implemented in Java |
Assignment 2 - Travel Simulation
The Rationale
The decorator design pattern is used to add new behavior or functionality to an object dynamically without altering its structure. The main rationale behind the decorator pattern is to allow developers to create a flexible and extensible system that can add new features to an object without changing its existing code.
The decorator pattern achieves this by creating a decorator class that wraps the original object and adds new behavior to it. The decorator class implements the same interface as the original object, so the client code can interact with it as if it were the original object. The decorator also has a reference to the original object and can call its methods to execute its behavior.
This design pattern is particularly useful in situations where you have a large number of objects that require different features, but it is not feasible or desirable to create a subclass for each combination of features. The decorator pattern allows you to add new functionality to an object at runtime by creating a decorator that adds the desired behavior.
A good explanation of the decorator pattern can be seen at Decorator, also known as Wrapper.
The UML
Here is the UML diagram for the decorator pattern:

Here are the components of the decorator design pattern:
Code Example - The Decorator
The following is a simple implementation of the decorator pattern:
C++: Decorator.cpp.
C#: Decorator.cs.
Java: DecoratorMain.java.
Python: Decorator.py.
Common Usage
The following are some common usages of the decorator pattern:
Code Problem - Button Decorator
We have an implementation for drawing a button. We would like to add a feature to this implementation.
The feature is a border. The following code implements the decorator design pattern to do so:
Component.h, the component interface,
Button.h, the concrete component,
Decorator.h, the decorator interface,
BorderDecorator.h, the concrete decorator,
ButtonMain.cpp, the client.
Modified Code Problem - Button Wrapper
A class that is weakly related to the decorator pattern is the wrapper. Wrappers are very useful in ensuring
reliable code. The following example uses component wrappers to ensure memory is always cleaned up, even if
the programmer forgets to delete the allocated memory. This wrapper class takes an interface (component in this case)
as an argument and deletes it when its destructor is invoked similar to a smart pointer. The concept of a wrapper class
to ensure reliable code can be applied to the creation and deletion of threads, the opening and closing of files, etc...
Component.h, the component interface,
Button.h, the concrete component,
Decorator.h, the decorator interface,
BorderDecorator.h, the concrete decorator,
ComponentWrapper.h, a wrapper class for a component object,
ButtonMain.cpp, the client.
The Rationale
The Composite pattern is a structural design pattern that allows you to compose objects into tree structures to represent part-whole hierarchies. The basic idea behind the Composite pattern is to treat individual objects and compositions of objects in a uniform way so that they can be manipulated in the same way. By treating individual objects and compositions of objects in the same way, the client code becomes simpler and more consistent. The client code does not need to know whether it is dealing with a single object or a composition of objects, making it easier to use and less error-prone.
The UML
Here is the UML diagram for the composite pattern:

Here are the components of the composite design pattern:
Code Example - The Composite Design Pattern
The following is a simple implementation of the composite pattern:
C++: Composite.cpp.
C#: CompositeMain.cs.
Java: CompositeMain.java.
Python: Composite.py.
Common Usage
The composite design pattern is commonly used in the software industry in situations where a group of objects needs to be treated in the same way as a single object. Here are some common use cases:
Code Problem - Employment
We have a company with managers and software engineers. Managers manage software engineers but they can also manage
other managers. The composite pattern is employed in the following example to show the collection of the relationships
between managers and other managers, and managers and software engineers:
Employee.h, an interface class (component),
SWEngineer.h, a concrete class that represents a leaf node,
Manager.h, a composite concrete class that has one or more child components,
Employment.cpp, the main function.
For a more detailed explanation of this problem, see Composite Design Pattern, the Organization.
Code Problem - Enhanced Employment
We can enhance the above code by adding the hardware engineer as another concrete class that represents a leaf node,
and by taking advantage of the add and remove employee functions, in case the company
undergoes re-organization. We can also add a display employee function that takes an index into the employee vector:
Employee.h, an interface class (component),
SWEngineer.h, a concrete class that represents a leaf node,
HWEngineer.h, a concrete class that represents a leaf node,
Manager.h, a composite concrete class that has one or more child components,
Employment.cpp, the main function.
You're building an Agenda Builder for a two-day software workshop. The agenda consists of Tracks, which contain Modules, which contain Lessons. Tracks and Modules can also contain other Modules (nesting). The platform must let organizers:
Domain Rules
title, minutes, and cost.title and a list of children (Lessons or Modules).getDuration(), getCost(), print().Constraints & Acceptance Criteria
Example Structure
See a potential solution here.
You're building an e-commerce configurator for a software workshop's Access Pass. Each attendee must purchase at least a Base Pass, and can optionally add a variety of premium enhancements. Organizers want to combine these enhancements in any order without creating a separate class or pricing rule for every combination.
What the Platform Must Do
getPrice(), getBenefits(), and describe().See a potential solution here.
After a multi-day software workshop, organizers collect large volumes of feedback from participants. This feedback must be analyzed using different analysis methods and reported through different channels.
What the System Must Do
Constraints & Acceptance Criteria
Examples
See a potential solution here.