Model the product as a component interface (e.g., AccessPass) declaring getPrice(), getBenefits() (a list/summary of features like "recording", "captions", "mentor minutes"), and describe() (a human-readable label). The BasePass is the concrete component. Each enhancement (Recording, Captions, Translation, Mentor Session, Code Review, Certificate) is implemented as a Decorator that wraps another AccessPass.

Each decorator forwards calls to the wrapped pass and then augments the result: adds its own price to getPrice(), appends its feature markers to getBenefits(), and enriches describe() with a short tag (e.g., "+ Recording").

Because all decorators share the same interface, clients can stack them in any order and still treat the result as a regular AccessPass. Adding a new enhancement later (e.g., "Office Hours Pack") requires introducing a single new decorator class without changing existing ones. Removing an enhancement simply means unwrapping that decorator; its cost and descriptors disappear automatically.

Responsibilities by Role

Outcome: no subclass explosion, fully composable add-ons, and a single uniform interface for pricing, benefit aggregation, and user-facing descriptions-exactly what the Decorator pattern is built for.