To solve the Workshop Agenda Builder problem, we apply the Composite design pattern. This lets us treat both individual lessons and groups of lessons (modules or tracks) with the same interface.
In short: Leaves (Lessons) and Composites (Modules/Tracks) share a common contract, so the client code doesn't need to worry about whether it's working with one lesson or an entire subtree.
The solution introduces an abstract component WorkshopItem
with three core operations:
getDuration() returns total minutesgetCost() returns total costprint() returns a text outline with indentationLesson acts as the Leaf, directly returning its own duration and cost, and printing a single line of text. Module and Track are the Composites: they hold a collection of children (which can be Lessons or other Modules). Their operations work by recursively aggregating values from children.
This design means you can:
The result: a clean, extensible, and uniform way to manage a workshop agenda where client code never has to distinguish between "one item" and "many items."