Enterprise Integration Zone is brought to you in partnership with:

Ayende Rahien is working for Hibernating Rhinos LTD, a Israeli based company producing developer productivity tools for OLTP applications such as NHibernate Profiler (nhprof.com), Linq to SQL Profiler(l2sprof.com), Entity Framework Profiler (efprof.com) and more. Ayende is a DZone MVB and is not an employee of DZone and has posted 485 posts at DZone. You can read more from them at their website. View Full User Profile

Design Patterns in the Test of Time: Decorator

11.22.2012
| 3648 views |
  • submit to reddit

 

The decorator pattern is a design pattern that allows behaviour to be added to an existing object dynamically.

More about this pattern.

I don’t have a lot to say about this pattern.

Hipster Ariel - Decorator? Used it before it was cool

The decorator pattern is still just as useful if not more so as the time it was initially announced. It forms a core part of many critical function of your day to day software.

The most obvious example is the notion of Stream, where you often decorate a stream (Buffered Stream, Compressing Stream, etc). This example is valid not just for the .NET framework, I can’t think of a single major framework that doesn’t use the Stream abstraction for its IO.

Then again, the cautionary side, people try to use it in… strange ways:

        public abstract class CondimentDecorator : Beverage {}

         

        public class Mocha : CondimentDecorator

        {

            private Beverage m_beverage;

         

            public Mocha(Beverage beverage)

            {

                this.m_beverage = beverage;

           }

        

           public override String Description

           {

               get

               {

                   return m_beverage.Description + ", Mocha";

               }

           }

        

           public override double Cost()               

           {                                      

               return 0.20 + m_beverage.Cost();

           }

       }

Something like this, for example, is a pretty bad way of doing things. It assumes a very fixed model of looking at the universe, which is just not true. Decorator works best when you have just a single I/O channel. When you have multiple inputs & outputs, decorating something becomes much harder.

In particular, implementing business logic like the one above in decorators make it very hard to figure out why things are happening. In particular, CachingDecorator is something that you want to avoid (better to use infrastructure or a auto caching proxy, instead).

Recommendation: It is a very useful pattern, and should be used when you actually have one input / output channel, because that is a great way to allow to dynamically compose the way we apply processing to it.


Published at DZone with permission of Ayende Rahien, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)