The Decorator Design Pattern adds responsibilities to an object at run time without changing its class. Wrapper objects preserve the common interface, so application code can treat a decorated object like the original object. section 14.0 section 14.3.3
A ticket application makes the problem concrete. Base tickets can gain a pregame party, VIP seating, or drink coupons, each contributing behavior and cost. Hardcoding these options in Ticket makes additions, removals, and modifications require changes to that class and exposes enhancement details. section 14.3 section 14.3.2
Refactor the design as a nested chain of compatible objects:
- Define an abstract Ticket interface with get_cost(). section 14.3.3
- Represent the undecorated object with BaseTicket. section 14.3.3
- Make Decorator a Ticket subclass that stores the wrapped Ticket and returns its own price plus the wrapped object's cost. section 14.3.3
- Implement each enhancement as a small decorator, such as Party, VIP, or Coupon. section 14.3.3
- Build combinations by repeatedly wrapping the current Ticket object; multiple instances and arbitrary ordering are supported. section 14.3.3
Enhanced ticket
Start with BaseTicket, then wrap it with Party, VIP, Coupon, and another Coupon. Each get_cost() call adds one decorator's price while delegating to the object it wraps, producing a total of $85.
Figure 14.12 The generic model of the Decorator Design Pattern. Compare it with figure 14.11. A ConcreteComponent object by itself is a Component. A ConcreteComponent wrapped by Decorator objects is also a Component. The component member variable of superclass Decorator points either to a ConcreteComponent object or to a Decorator object. This chain implements the nested wrapping of the Decorator objects.
The generic model shows a ConcreteComponent and its decorators sharing the Component interface while a component link forms the wrapping chain. section 14.3.4

