Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Structural Design Pattern (Part 4)

, 11 Oct 2011 LGPL3
Rate this:
Please Sign up or sign in to vote.
An intro to the Decorator Pattern

This is a continuation to the previous post. Please note that this post will be a long one, so if you have time, keep reading :)

Decorator Pattern

What

This pattern says “Defines attaching new responsibility to the object dynamically”. What it says is that, some times you require to give an object some extra/additional responsibility at a later point of time so that you can perform something else with it. Based on some conditions, this object should take or have some responsibility so that it can perform multiple roles in a system.

By reading the above lines, one might get confused as this pattern would fall under Behavioral rather than in Structural category. From the overview, it looks like we are adding some behaviors to an object, but actually we are adding a different structure via responsibility to the object at some point where its output will be in terms of the behavior changes.

Take this example, since we are all humans, as soon as we enter the premises of our work place, we take up the new responsibility of being an employee. As long as we are inside the premises, we are identified as the Employee of that structure. When we fall out of that structure or separated from that structure, we fall back to take up the old responsibility, that is the human responsibility. But not every human out there is capable of taking this responsibility structure called Employee due to various reasons.

Similarly, as soon as we enter a car, we take up the responsibility of either a passenger (broadly classified) or a driver (specifically classified). That means to take up the responsibility structure as driver, one must exactly possess the knowledge about driving. Then only can you put these two components together to make it work perfectly.

You should note one thing, the structure which is an added responsibility here should exactly fit into another component, not every component will fit with this responsibility component, like I can not make a dog sit in the driver seat and make it drive. Although logically it might make sense (assuming the dog knows how to drive due to its phenomenal talent like in movies), realistically it is not preferred or acceptable ;).

Why

Without using this pattern, we are in a big soup. The design of the system would turn out to be very complex, since for each responsibility, we ought to create many new objects and then we should make those objects talk to each other. But all these would be defined statically, but later at run time, it would be very tedious to define this behavior. Not only that, we can’t abide to the SOLID software design principles either. Every time there needs to be added a new behavior, we need to modify the existing structure, which is a big cost for us.

Let's take the same example of being a driver who is a human too. Now what could happen if this pattern is not used? We would be having an object Human and another object called Driver who has replicated the behaviors of humans too. Like these two, many objects would be required. Not only this, any one would make the driver object replicate the behavior of a non-human as well. The whole system will be a mess.

Note that as I said in Part 2 article, patterns are not always the solution for a problem. So if the above said problem can be easily solved and maintained for a long time, then patterns are of no use at all here. But the above said system would be very difficult to design and maintain without these patterns where several components of a system interact with each other.

How

Let's look at the code I wrote to simulate this pattern. As I said, I have written very simplistic code.

The code I am simulating here is about a bottle which we can call a Beverage bottle. The core structure of the bottle is the same, but on different occasions or on different sub-category brands, I need to give a different coverage or responsibility such that its depiction at the end is different.

For example, if a Coca Cola bottle core shape is fixed (which it is in real world) then for Diet Coke, Normal Coke, Lime flavored, etc., flavor type categories, I need to give a different coverage color or look to it. At the end of the production line, I would get the same shaped bottle (shape is a trademark of Coca Cola) but with different representations; look at the code now.

public interface IBeverageBottle
{
    string GetDescription();
    double GetCost();
}
public class BeverageBottle : IBeverageBottle
{
    public string GetDescription()
    {
        return “Basic Beverage Bottle”;
    }
    public double GetCost()
    {
        return 5;
    }
}

As you can see from the above code, I have a beverage bottle interface which has two methods where one gets its default description and the other gets its basic cost.

So if a vendor wants just a basic model of the beverage bottle, they would just call these methods directly. But if they want a category of sub-brand like flavored, etc., then let us see the responsibility structure code which we need to add to this basic model at some point or at run time.

picture-11.png

As you can see from the above code, I have a few additional responsibility structures which I am supposed to add to the basic beverage at a later point in time, i.e., whenever I need to.

Let us look at the usage point of this pattern in the below code:

picture-1.png

Where

Let me show you some examples in real world where we use it knowingly or unknowingly. Although I gave a few examples above, I think a picture speaks more than words:

picture-1.png

Note: I don’t have anything against Jobs please. I respect his talents.

picture13.jpg

  1. As the picture depicts, any picture can’t fit into a photo frame, like in my example, anything or anybody can not be a car driver.
  2. As in the example of the beverage bottle, this picture tells you pretty much about the same scenario.
  3. We wrap or decorate gift boxes with something, but not anything can be used to decorate them. Yes, it sounds it can be done so logically, but realistically, it does not sound correct.

Well, that’s all dear friends. I am sorry if it’s too lengthy, but I wanted to make every point clear.

Look out for my next post in a continuation to this.

Thanks :)

P.S.: Your valuable comments and votes are well appreciated.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author

zenwalker1985
Software Developer (Senior) Siemens
India India
A .net developer since 4+ years, wild, curious and adventurous nerd.
 
Loves Trekking/Hiking, animals and nature.
 
A FOSS/Linux maniac by default Wink | ;)
 
An MVP aspirant and loves blogging -> https://adventurouszen.wordpress.com/
Follow on   Twitter

Comments and Discussions

 
QuestionNice Post But Unbale to find Part 1 , 2 ,3 PinmemberGourav02078413-Oct-11 3:37 
AnswerRe: Nice Post But Unbale to find Part 1 , 2 ,3 Pinmemberzenwalker198513-Oct-11 4:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150305.1 | Last Updated 11 Oct 2011
Article Copyright 2011 by zenwalker1985
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid