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

Authentication using Social Networking portals(Facebook, Gmail, and Yahoo)

There are tons of sites, which offer sign on using the social networking site credentials (Facebook, gtalk, twitter and the list continues).It can be termed a “SINGLE SIGNON” and offers a lot of benefits compared to traditional database authentication approach. However, not storing user credentials in the DB imposes an additional risk. How to track who all logged into the system. Now the question is, which approach to follow. The best approach is to use inbuilt asp.net users for storing the logging info about user activities and using single signon technique for authentication. This article will explore the approach and provide the details of implementation using some third party libraries and customizing it to the requirements. The Authentication will be done using the following networking portals Yahoo  Gmail Facebook    Special thanks to my friend Sumit Khandelwal, for implementation of Facebook part (in fact he did it all!!) Except Facebook, all other ca...

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...

WPF Overview-Part-II

This post is in continuation to the last post. In this Post I’ll be exploring the Dependency Properties Dependency properties are similar to CLR properties with more advanced and complex features. The main difference between the CLR properties and dependency properties is, that the value of a normal .NET property is read directly from a private member in your class, whereas the value of a DependencyProperty is resolved dynamically when calling the GetValue() method that is inherited from DependencyObject . In case this description did not make sense, no need to worry, It will become clear by the time you reach end of this article. How the Value is Resolved in Dependency properties Every time a dependency property is accessed, it internally resolves the value by following the precedence from high to low. It checks if a local value is available, if not, check if a custom style trigger is active and I the similar manner continues until it finds a value. At last the default value is alwa...