13 August 2012
Attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality
This design pattern would be useful when you consider the attributes of of a Super Hero. A hero can have a normal strength and yet have a power that enhances his strength beyond human norms. Also heros can achieve greater strength via mechanical or pharmaceutical means.
This is achieved by the decorator objects swallowing the core object and other decorator objects. This swallowing is called composition. Any object is then accessible as long as it is part of the composition. This access is usually defined through abstraction or an interface. Through the interface the innermost object to the outermost can make calls through the agreed method to the other objects.
Taking this basic concept we can then build the class structure below. The classes in italics are abstract.
Finally we can build these classes and objects in Ruby as seen in the following code. One difference between the code and the class diagram is that Ruby doesn’t need to define the abstract classes. It more or less defines an interface using a module.
module HeroDecorator def initialize(heroDecorated) @heroDecorated = heroDecorated end end class Hero def name "Bob" end def description "He is really strong" end def strength 40 end def intelligence 10 end end class CombatDrugs include HeroDecorator def strength @heroDecorated.strength() + 40 end def intelligence @heroDecorated.intelligence() + -5 end end class SuperStrength include HeroDecorator def strength @heroDecorated.strength() + 40 end def intelligence @heroDecorated.intelligence() + 0 end end bob = CombatDrugs.new(SuperStrength.new(Hero.new())) puts "Strength=" + bob.strength.to_s puts "Intelligence=" + bob.intelligence.to_s