Decorator Pattern Motivation: class explosion! - Starbuzz example, with condiments What design principles not being followed? - Review what they are The Open-Closed Principle: Classes should be open for extension, but closed for modification. - I.e., it should be possible to add behavior to a class without changing its implementation Example with Coffee (whip, mocha, dark roast coffee) Features of Decorator - Have the same supertype as the decorated object - Can thus pass it around where the original was expected - One or more decorators "wrap" an "underlying" object - The decorator adds its own behavior before or after delegating to the underlying object - Objects can be decorated at run-time - Need not be enumerated, e.g., in a class hierarchy, at compile time. Decorator and the Open-Closed Principle - Extensibility comes via polymorphism: decorators have the same type as the objects they wrap, so new versions can be used where the old type is expected. - Lack of modification comes via composition: don't change the underlying object, but rather delegate to it for part of the behavior, and then extend the behavior in the wrapper. Decorator UML Diagram Extend the example to deal with sizes in coffee - setSize() and getSize() in Beverage - three sizes - condiments cost more with size Misfeatures - Too many possibilities (hard to follow all the delegations) - Performance degradation Examples of Decorators in "real life" - java.io (p. 100) - the large variety of choices can be overwhelming: the downside of decorator - Example: write a LowerCaseInputStream - project 1 Cache Servlet Notes - Client classes cannot assume a particular class of the supertype - whether directly or through instanceof - need to operate on the type abstractly