Decorator Design Pattern

By Mithun Bose at January 02, 2010 17:41
Filed Under: .NET Framework, C#, Design Patterns

What is it?

 In simple words decorator enables to attach additional responsibilities(Properties) or behaviours (Methods) to an object dynamically without actually having to subclass or inherit it.

Whats the point?

 The first question which comes to mind is why not inherit or subclass the object in the first place, why use the decorator pattern? Well, some of the explaination to this questions are:

  • That class that is being "decorated", doesn't allow subclassing.
  • You want to add state or behaviour to the object dynamically.
  • You want to make changes to some object in a class without affecting others.
  • You want to avoid inheriting the object as that results in too many classes and inheritance hierarchies.

Class Diagram

The following diagram shows structure of typical decorator pattern, the diagram was taken dofactory.com

 

Decorator Pattern Class Diagram

The center of the above UML diagram is the Decorator class. It inherits from Component interface and also has a instance of Concrete object. This Decorator decorates the ConcreteComponent class. In the following section I've explained the pattern with an example.

Example

I've looked many examples on the various blogs and books, most of examples that I found were related to enhancing or adding functionality to an Image.  For e.g. adding border, tag, watermark etc as an added behaviour to an existing Image component. These are great examples and does describe the pattern very well; however, I wanted to share an example which I've used in my day to day work. I am working in telcoms domain for last 10 years and I've used decorator pattern a few times, one of the examples is as below.

Scenario

So the scenario was that we had a third party object packaged in a .NET DLL, this Object was responsible to send SMS(Text) messages. It did work very well. Some months down the line inevitably there was a new business requirement i.e. we should also be able to send a MMS(Picture) message with the SMS. The third party object could not be inherited. I had two options to add this fucntionality

  • Write a seperate component, which would only be used to send Picture Messages.
  • Decorate the third party component and add picture messaging facility as an added behaviour.

The second option was the logical way forward.

The third party class library had following interface and a class

 

1. ISMS Interface

 

namespace ThirdPartyLibrary
{
    public interface ISMS
    {
        void SendSMS(string smsText);
    }
}

 

2. SMS Concrete Object
namespace ThirdPartyLibrary
{
    public sealed class SMS : ISMS
    {
        
        public void SendSMS(string smsText)
        {
            /* Business logic to send SMS text message */
        }
       
    }
}

 

 

The requirement was to add additional behaviour in the above SMS concrete object, the additional behaviour would send picture message along with the text message.

The class below is the decorator pattern class which implements the additional functionality

public class SMSMMS : ThirdPartyLibrary.ISMS
    {
        ISMS sms;
        string pictureMessageLocation = "D:/SomePicture.jpg";
        public SMSMMS(ISMS _sms)
        {
            sms = _sms;
         
        }
        public void SendSMS(string smsText)
        {
            sms.SendSMS(smsText);
            SendPictureMessage();
        }
        void SendPictureMessage()
        {
            /* Picture Message sending logic */
        }
        
    
    }
}

 So as you'll notice the example starts with third party ISMS interface and a simple SMS component class that implements it. The above decorator class also implements the ISMS interface, and it includes a declaration of an ISMS, which is the object that it is decorating. Decorators always needs to know about the object that it is decorating, and in the example I've used the constructor injection. Notice in the constructor that I am passing ISMS component, which is then assigned to the sms variable. 

 

It then implements the SendSMS function, which calls the decorated object's SendSMS method and then also calls the SendPictureMessage method, which is the added behaviour.

Now how should I use this decorator, see below an example client code:

class Client
    {
        ISMS smsmmsObj = new SMSMMS(new SMS())
        public void sendMessage()
        {
            smsmmsObj.SendSMS("Test Text Message");
        }
        
   
    }

If you notice the client just created an object of type ISMS and called the same method "SendSMS"; however, this time the object not only sends SMS but also sends a picture message with it. The client didn't care or even know that it was the decorated object.

 

 I hope this post helped you understand the simple example of Decorator pattern.

 

 

Comments

2/17/2010 9:31:50 PM #

Računalniški servis

Useful and nice information. I am going to subscribe your blog. Tnx.

Računalniški servis Slovenia |

3/19/2010 12:27:53 PM #

Keesha Sciotti

I have read a few of the articles on your website now, and I really like your style of blogging. I added it to my favorites webpage list and will be checking back soon. Please check out my site as well and let me know what you think. % BLOGTITLE %

Keesha Sciotti United States |

3/21/2010 3:50:20 PM #

Legalsounds

Wow!, this was a real quality post. In theory I'd like to write like this too - taking time and real effort to make a good article... but what can I say... I keep putting it off and never seem to get something done

Legalsounds United Kingdom |

3/22/2010 1:17:27 AM #

Kelsie Mervyn

This is a fantastic post, I found your blog page browsing bing for a related theme and arrived to this. I couldnt find to much other information and facts on this piece of content, so it was great to discover this one. I definitely will end up being back to look at some other articles that you have another time.

Kelsie Mervyn United States |

3/23/2010 1:42:23 PM #

metal roofing

Thanx for the effort, keep up the good work Great work, I am going to start a small Blog Engine course work using your site I hope you enjoy blogging with the popular BlogEngine.net.Thethoughts you express are really awesome. Hope you will right some more posts.

metal roofing Poland |

3/23/2010 5:17:03 PM #

canon ef 50mm f/1.8 ii camera lens

Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. Any way I'll be subscribing to your feed and I hope you post again soon.

canon ef 50mm f/1.8 ii camera lens United States |

3/24/2010 1:26:32 AM #

Aiko Soomaroo

I'm glad I discovered this blog page, I couldnt find any information on this subject matter prior to. Also operate a website and if you're ever interested in doing some guest writing for me if possible feel free to let me know, i'm always look for people to check out my webpage. Please stop by and leave a comment sometime!

Aiko Soomaroo United States |

3/26/2010 3:22:09 AM #

Table lamp

Where did you get this theme. Is this Wordpress?

Table lamp United States |

3/26/2010 9:37:27 AM #

crane hire

Hi vey nice interesting blog im from london i found this on bing I'm in the crane hire company business,i found this blog very interesting good luck with it i will return to this blog soon

crane hire United Kingdom |

About the author

I am a professional software developer based in London, England. I specialize in developing enterprise application and integration framework in C#, SQL Server, ASP.NET. 

My area of interests include SOA using WCF, Web, Business Intelligence and Database programming. I am a Computer Science Graduate and Microsoft Certified Professional Developer in enterprise application.