Skip to main content

Structural Patterns: Decorator Pattern


Decorator Pattern

The Decorator pattern provides a way of attaching new state and behavior to an object dynamically.
 The original object never comes to know that it is being “decorated”.

One important point to remember while implementing the Decorator pattern is that the decorator (class that takes the responsibility of extending or decorating the base class) will inherit the original class and  also contain an object of it

This Pattern does is useful when you want to extend the base class functionality, but do not want to use subclasses and inheritance.
In shot and sweet terms. OPEN for extension, Closed for modification (do not confuse, if you have heard it somewhere else)

The Decorator pattern’s key feature is that it does not rely on inheritance for extending behavior.
(i.e. To extend the behavior of existing object, it does not need to inherit all the characteristics of the object to be decorated).

.
Is-a Relationship

The is-a relationship indicates if a class inherits from Interface the class objects can be used wherever Interface objects are expected.

To extend it further, if there are two classes ClassA and ClassB and both derive from an Interface IMyInterface, then any other class ClassD can use the ClassA and ClassB objects interchangeably.

It simply means if at any place object of ClassA is expected, if you pass object of ClassB, it should be fine.
This concept is the Core of Decorator Pattern.


The Following example explains the theory discussed so far


//Fresher Interface
public interface IFresher
{
    string Name { get; set; }
    string CodingSkills();
}
//Concrete Fresher Class
public class FreshDeveloper : IFresher
{
    private string d_name;
    #region IFresher Members

    public string Name
    {
        get{return d_name;}
        set{d_name = value;}
    }

    public string CodingSkills()
    {
        return string.Format(" AS a Fresher the developer{0} has {1} programming skills", Name, "Non Satisfactory");
    }

    #endregion
}
//Concrete One Year Experienced
public class OneYearExperienced : IFresher
{
    private IFresher d_Developer;
    public OneYearExperienced(IFresher developer)
    {   d_Developer = developer; }
   
    private string Enhancedskills()
    {
        return string.Format(" AS One Year Experienced, the developer{0} has {1} skills", Name,"Improved Coding");
    }


    #region IFresher Members

    public string Name
    {
        get{ return d_Developer.Name;}
        set { d_Developer.Name = value; }
    }

    public string CodingSkills()
    {
      string s1=  d_Developer.CodingSkills();
      string s2=  Enhancedskills();
      return s1 + "" + s2;
    }

    #endregion
}
//concrete  FiveYearExperinced
public class FiveYearExperinced:IFresher
{
   private IFresher d_fexp;
   public FiveYearExperinced(IFresher developer)
   {
       d_fexp = developer;
   }
 
    private string Enhancedskills()
    {
        return string.Format(" AS Five Year Experienced, the developer{0} has {1} skills", Name,"Excellent Coding");
    }

   #region IFresher Members

   public string Name
   {
       get {return d_fexp.Name; }
       set { d_fexp.Name = value; }
   }

   public string CodingSkills()
   {
     string s1= d_fexp.CodingSkills();
      string s2= Enhancedskills();
      return s1 + s2;
   }

   #endregion
}

Let’s Call it passing the object of fresher

IFresher developer = new FreshDeveloper();
developer.Name = "Pradeep";
Response.Write(developer.CodingSkills());

The Result:
AS a Fresher the developer Pradeep has Non Satisfactory programming skills

Now let’s pass the fresher object to OneYearExperienced Class
IFresher developer = new FreshDeveloper();
developer.Name = "Pradeep";
OneYearExperienced oexp = new OneYearExperienced(developer);
Response.Write(oexp.CodingSkills());

The Result:
AS a Fresher the developer Pradeep has Non Satisfactory programming skills
AS One Year Experienced, the developer Pradeep has Improved Coding skills

Now let’s pass the OneYearExperienced object to FiveYearExperinced Class

 IFresher developer = new FreshDeveloper();
 developer.Name = "Pradeep";
 OneYearExperienced oexp = new OneYearExperienced(developer);
 FiveYearExperinced fexp = new FiveYearExperinced(oexp);
 Response.Write(fexp.CodingSkills());

The Result:
AS a Fresher the developer Pradeep has Non Satisfactory programming skills
AS One Year Experienced, the developer Pradeep has Improved Coding skills
AS Five Year Experienced, the developer Pradeep has Excellent Coding skills


Note:

1. If the base class (that needs to be decorated), does not have virtual method available for over-riding, then only we need to use Interface.
2. An important point about the Decorator pattern is that it is based around new objects being created with their own sets of operations.

There are still some aspects to Decorator pattern, like implementing with abstract classes and virtual methods that have not been covered here.

Hope this was helpful.

Till next time we connect, Happy coding!!

Comments

Popular posts from this blog

Asp.Net 4.0: An Overview-Part-III

This is the last post in the series which will explore the following new features of ASP.Net 4.0  Performance Monitoring for Individual Applications in a Single Worker Process Web.config File Refactoring Permanently Redirecting a Page Expanding the Range of Allowable URLs Performance Monitoring for Individual Applications in a Single Worker Process It is a common practice to host multiple ASP.NET applications in a single worker process, In order to increase the number of Web sites that can be hosted on a single server. This practice results in difficulties for server administrators to identify an individual application that is experiencing problems. ASP.NET 4 introduces new resource-monitoring functionality introduced by the CLR. To enable this functionality, following XML configuration snippet is added to the aspnet.config configuration file.(This file is located in the directory where the .NET Framework is installed ) <?xml version="1.0" encoding="UTF-8"

SOLID principles -Code Samples and Free Ebook

I planned to write code samples for SOLID principle implementations, however I am a firm believer of " NOT RE-INVENTING THE WHEEL ", when all you need is use the wheels and make a new CAR. Going by the ideology, I have found an excellent  SOLID principles FREE -Ebook ( covering all aspects of SOLID design principles, with Code sample). This book is an excellent visual aid to remember these principles, as it uses Motivational posters for explaining SOLID design principles. One additional advantage to the above mentioned book is the Code-Refactoring ebook . Both of these books can be downloaded from this EBOOK download Link Both of these books can be downloaded form here. Hope this book proves useful... Till next we connect.... Happy Learning..

Covariance and Contravariance-General Discussion

If you have just started the exploration of .Net Framework 4.0, two terms namely Covariance and Contravariance might have been heard. The concept that these terms encapsulate are used by most developer almost daily, however there has never been any botheration about the terminologies. Now, what actually these terms mean and how are these going to affect us as a developer, if we dive in to the details. The simple answer is it’s always good to know your tools before actually using them. Enough philosophy, let’s get to the business. Starting the discussion let me reiterate that in addition to Covariance and Contravariance, there is another terminology, Invariance. I’ll by start here by diving into the details of Invariance and then proceed further. Invariance: Invariance can be better understood by considering the types in .Net.>net has basically two type, value-types and reference-types. Value types (int, double etc) are invariant i.e. the types can’t be interchanged either