Design Patterns – Decorator Pattern

Following up on the Observer/Event Pattern, it’s time for the third pattern, the Decorator Pattern.

The definition: “Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

Continuing on our little game, let’s say we are able to create buildings and have just an IBuilding interface and one building.

Simple Building

Each building has a description and a given power usage cost, which is simply hardcoded in the class right now.

After a while, our boss hired an external company to take over development with regards to the buildings and tasked them with making buildings upgradeable.

The first approach they took was too simply add new building classes to the game, for each possible upgrade.

Class Explosion

This however leads to an infinite amount of possibilities and a nightmare to maintain.

If we look at the definition of the Decorator Pattern, it seems to offer a good alternative to all this inheriting to add in new functionality.

Also, adding additional responsibilities dynamically means we don’t have to change the code of the IBuilding and NormalBuilding either. By doing this we are honoring the Open/Closed Principle, which says “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification“.

How are we going to add these additional things dynamically? We’ll decorate our initial NormalBuilding with upgrades, giving us flexibility to equip a building with any upgrade combination we like.

When we mention decorating, think about wrapping. We are going to wrap an instance of IBuilding in a decorator, acting as a shell around the class, passing calls to our decorator along to the wrapped instance, modifying the results when needed.

It’s also possible to chain decorators together, making it possible to decorate a NormalBuilding with two Turrets, a SAM installation and a Laser. This is done because a decorated object is still of the type IBuilding, and can be decorated again and again.

Eventually we’ll end up with the following class diagram. Note, the WrappedBuilding has a protected getter and a private setter.

Decorator Pattern

Now we have a set of buildings, which implement IBuilding and one decorator base class, BuildingUpgradeDecorator, from which all possible decorations inherit. This decorator class has to implement IBuilding as well, so it can be re-decorated.

With the above classes, it’s possible to compose buildings as we desire, as shown below.

Decorator Usage

When we run this code, the call to the Power property is being passed through all decorators to the lowest level, our NormalBuilding, and returned all the way back, getting incremented with the additional power usage for each decorator/upgrade in the mean time.

Decorator Output

I’ve uploaded the solution again so you can have a look on how the decorator base class and individual decorators are programmed.

Some additional information on the Decorator pattern:

12 reacties op “Design Patterns – Decorator Pattern”

  1. [...] more at http://blog.cumps.be/design-patterns-decorator-pattern/ Filed under: C#, General Software Development, Visual Studio, .NET, Design [...]

  2. Thanks for the simple but great posts David. Please keep them coming. :)

  3. [...] Design Patterns – Decorator Pattern – David Cumps continues his series on design patterns with a look at the decorator pattern. Also check out his followup to Thursday’s post on the Observer/Event pattern (linked in the left nav) [...]

  4. jean zegt:

    Nice article!

  5. [...] David Cumps » Design Patterns – Decorator Pattern Continuing on our little game, let’s say we are able to create buildings and have just an IBuilding interface and one building. (tags: blog.cumps.be 2008 mes5 dia29 at_home design_patterns C# decorator blog_post) [...]

  6. Arch4ngel zegt:

    If you keep posting stuff like this, I’ll get hooked and will have to watch every morning if you didn’t post something interesting.

    I already bookmarked you. Keep posting! You’ve become part of my daily routine!

    Cheers!

  7. David Cumps zegt:

    Thanks :) It’ll be a little slower this week, I’m currently in London for work, with little time to read and write :(

    But at least I’ll be back in Belgium next week :)

  8. [...] However, when we need to add new units, we need to open up this class every time again and change inside of it, which violates the Open/Closed Principle we talked about last time. [...]

  9. Harish zegt:

    Great posting on patterns , easier to digest .
    Can we get an index please ?

  10. David Cumps zegt:

    An index like this: http://blog.cumps.be/tags/design-patterns/ ?

    Or just an overview of what is yet to come?

  11. [...] Design Patterns – Decorator Pattern [...]

  12. Kalid zegt:

    Hi David, I just wanted to say thanks again for the crisp, clean & downloadable examples. It really helps hit the idea home — hope you keep posting!

Reageer