The TechGuy

April 28, 2011

Design Patterns by Examples – Decorator Pattern

Introduction

This series of articles will help you to build a good understanding of design patterns using different examples from real life and some from well-known frameworks or APIs. There are many articles around the web that discuss design patterns but they sometimes lack appropriate examples to quote. So, either their purpose stays unclear or we cannot memorize the patterns longer and sooner they slip out of mind. More importantly, we understand them but to employ within our problem domain is again out of the quest.

Expert designers reuse solutions that they had worked on in the past and they re-engage them whenever they faced with the same problems. Rookie designers can also use design patterns to solve their problems efficiently. This article is intended to help both naive and expert developers by making them understand the application of patterns and opening up new dimensions in solutions domain.

Decorator Pattern

For the sake of continuity, let’s look at the formal definition first.

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.


At this stage you might not understand it clearly but as you go through the whole article you will gain better understanding of the pattern and would defiantly want to use it to solve your own domain problems.

In this part of the article I totally concerned about dynamic behaviors that most readers expect from pattern, decorator is not just design as well as analysis pattern too, we will discuss this in next part. So ignore NewState field in ConcreteDecoratorA for this time.

Problem Domain

To keep things simpler we take an example of a subsystem, where employees are working with different responsibilities (such as team members, team leads and a manager). A team member is responsible to do his assigned tasks and to coordinate with other members for the completion of group tasks. On the other hand, a team lead has to manage and collaborate with his team members and plan their tasks. Similarly, a manager has some extra responsibility over a team lead such as employee profiling, work assignment.

Following are the system entities and their behaviors:

Employee: calculate salary, join, terminate.

Team member: perform task, coordinate with others.

Team lead: planning, motivate.

Manager: assign task, employee profiling, create requirements.

There may be some other entities like Team, Task, etc. but my focus here is to convey the idea of a Decorator while keeping things simple and paying attention on root of pattern.

Traditional Approach

In such a system, the most followed approach is to make an employee super class and extend it to all three classes. Even this is an object oriented approach but it has some drawbacks.

Whenever a team member becomes a team lead, we have to create a new object of team lead and the previous object that points to that employee (team member) may be destroyed or archived. That’s not a recommended approach when employee is still a part of your organization. Same is the case with manager, when an employee turns into a manager from a team lead/team member.

Another case is when an employee can perform responsibilities of a team member as well as those of a team lead or a manager can perform team leads responsibilities. In that case you need to create two objects for the same employee which is totally wrong.

In these scenarios a team member/team lead can have extra responsibilities at run time. And their responsibilities can be assigned/revoked at run time.

Decorator Pattern Approach

Let’s see how design patterns help in these cases. If we look at Decorator Pattern it says:

Attach additional responsibilities to an object dynamically.

Wow, can it really solve my problem, let’s see.

At this moment we defector our previous approach in such a way that we always register just an Employee and TeamMember, TeamLead and Manager will be decorator of that employee object.

Now, if we want to change responsibilities of an employee to manager we just need a new Manager (Decorator) and assigning that employee to it will solve our problem. Same is the case when a team lead’s responsibilities are revoked, and some other member becomes team lead, we just need to swap employee objects within TeamMember and TeamLead decorators.

As for the case where an employee can perform the responsibilities of a team member as well as those of a team lead, we just need TeamMember and TeamLead decorators that are pointing to same employee object.

Employee (Decorated/Component)

Implementation of Employee is as follows:


public interface
Employee {

public void join(Date joinDate);
public void terminate(Date terminateDate);

// other behaviors may reside (see sample code)
}

EmployeeImpl

This is the core implementation class of Employee interface, EmployeeImpl is given below:


public class
EmployeeImpl implements Employee {


// other behaviors and properties may reside (see sample code)
public void join(Date joinDate){
print(this.getName() + ” joined on “ + joinDate);
}

public void terminate(Date terminateDate){
print(this.getName() + ” terminate on “ + terminateDate);
}
}

EmployeeDecorator (Abstract Decorator)

This is an abstraction of Employee decorator, EmployeeDecorator is given below:


public abstract class EmployeeDecorator implements Employee {

protected Employee employee;

protected EmployeeDecorator(Employee employee) {
this.employee = employee;
}

// other behaviors may reside (see sample code)

public void join(Date joinDate) {
employee.join(joinDate);
}

public void terminate(Date terminateDate) {
employee.terminate(terminateDate);
}
}

TeamMember/TeamLead/Manager (Concrete Decorator)

These are concrete implementations of EmployeeDecorator, classes are given below:


public class TeamMember extends EmployeeDecorator {

protected TeamMember(Employee employee) {
super(employee);
}

public void performTask() {
print(employee.getName() + ” is performing his assigned tasks.”);
}

public void coordinateWithOthers() {
print(employee.getName() + ” is coordinating with other members of his team.”);
}

}

public class TeamLead extends EmployeeDecorator {

protected TeamLead(Employee employee) {
super
(employee);
}


public void planing() {
print(this.employee.getName() + ” is planing.”);
}

public void motivate() {
print(this.employee.getName() + ” is motivating his members.”);
}

}

public class Manager extends EmployeeDecorator {

protected Manager(Employee employee) {
super
(employee);
}

public void assignTask() {
print(this.employee.getName() + ” is assigning tasks.”);
}

public void profileEmployee() {
print(this.employee.getName() + ” is profiling employees.”);
}

public void createRequirments() {
print(this.employee.getName() + ” is creating requirement documents.”);
}

}

Some Example from APIs

There are many application of decorator in our routine APIs, like in I/O Streams and Readers use decorator pattern extensively.

In this example FilterInputStream, BufferedInputStream, DataInputStream and PushbackInputStream are decorators and FileInputStream and ByteArrayInputStream are decorated objects.


InputStream inStream = new FileInputStream(“data.txt”);

Here inStream is a simple file input stream and



inStream = new BufferedInputStream(inStream);

Now inStream is decorated by BufferedInputStream decorator. At runtime the BufferedInputStream, which is a decorator, forwards the method call to its decorated object FileInputStream. The decorator will apply the additional functionality of buffering around FileInputStream.

SiteMash is also one of the examples of decorator pattern in java web frameworks to decorate page.

Basic steps to use Decorator

To implement the decorator pattern you can just follow these steps:

  1. Create an abstract class or interface that you want to decorate. (e.g; Employee) and provide concrete implementation of that class/interface by extending it.
  2. Create an abstract decorator (e.g; EmployeeDecorator) that contains pointer field of decorated class, decorator must extend same decorated class/interface. (e.g; Employee)
  3. Pass the object that you want to decorate in the constructor of decorator.
  4. Redirect methods of decorator to decorated class’s core implementation.
  5. Override methods where you need to change behavior.

Conclusions

  • Decorators are very flexible alternative of inheritance.
  • Decorators enhance (or in some cases restrict) the functionality of decorated objects.
  • They work dynamically to extend class responsibilities, even inheritance does same but in a static fashion (means compile time).

Design Patterns

The key to any solution is to understand the problem. When we have complete requirements of our problem domain, the proper analyses of those requirements will facilitate us when incorporating any possible changes in the future. We have to suggest some design that can support current requirements and any possible changes. Therefor we use our past experience or shared thoughts of experts (Design Patterns) to design an elegant, flexible and reusable solution, and try to avoid redesigning or at least minimize it.


Design patterns are solutions to design problems you find again and again in real world application development.

Design patterns are not actually APIs that can be programmed in classes and reused as they are, neither are they are not domain-specific designs for any application or module. Design patterns actually are guidelines for communicating objects and classes that are customized to solve a general design problem in a particular context.

About these ads

19 Comments »

  1. Excellent material

    Comment by imranlatif — August 11, 2011 @ 11:28 AM | Reply

  2. Thanks ,Excellent material, Quite a helpful help, I must say. Beginners like us could learn a lot from you.

    Comment by Abdul Rauf — August 11, 2011 @ 5:40 PM | Reply

  3. brilliant material, definetly learnt a lot

    Comment by benn — August 12, 2011 @ 7:37 PM | Reply

  4. nice!

    Comment by Cyrille Chris — August 14, 2011 @ 10:19 PM | Reply

  5. Excuse me but let me state my objection/confusion regarding this example.
    The concrete decorators adds more functionality by adding more methods. That make them incompatible with each other. That doesn’t sound clear enough so lets take an example, for brevity consider classic “decorator pattern” example of windowing system. If you wish to add a horizontal scroll bar functionality you decorate it with HorizontalDecorator, and if you want to add Vertical scrollbar you decorate it with VerticalDecorator. Consider a case when you want to add the vertical scroll bar to a window already decorated with horizontal scrollbar. Now if both decorators do not follow same interface, its not possible. I hope I have made my point.

    Comment by Copper — August 15, 2011 @ 9:18 AM | Reply

  6. [...] One of the best articles I had seen so far on decorator pattern Introduction This series of articles will help you to build a good understanding of design patterns using different examples from real life and some from well-known frameworks or APIs. There are many articles around the web that discuss design patterns but they sometimes lack appropriate examples to quote. So, either their purpose stays unclear or we cannot memorize the patterns longer and sooner they slip out of mind. More importantly, we unders … Read More [...]

    Pingback by Design Patterns by Examples – Decorator Pattern (via Zeeshan Bilal’s Blog) « Deviltechie's Blog — August 23, 2011 @ 4:54 AM | Reply

  7. I liked your article as it is written in such a way that i easily memorize and request you to write more on other patterns.

    But one thing that i feel, which will improve it further, is implementation i.e. how to use this design. For example, how an employee will behave after becoming team lead and similarly to manager or vice versa.

    Comment by Fahad Khan — January 7, 2012 @ 11:05 AM | Reply

  8. excellent article

    Comment by shabir — March 15, 2012 @ 11:55 AM | Reply

  9. Let me differ from others but having entirely new methods in decorators (e.g. team lead, team member, team manager having additional resposibilities of assigning or monitoring tasks) should not be part of decorator. Moreover we cannot use these functionalities when we try to convert decorator into the component as these are not part of component. In this case decorated object would be incompatible with the component base object and we cannot use the additional functionality as correctly pointed out by Copper.
    Ideally decorator is used for mixing and matching between some functionalities and additional/ dynamic behaviour is exposed through some core property of method of base component class only.
    Had there been a code where we actually use decorated object, this thing would have become clearer (There was code only upto the declaration of decorated objects but no code where we create concrete component and then decorate them with decorator).

    Comment by Rajeev — April 11, 2012 @ 4:31 AM | Reply

  10. Nice post. Recently I posted another implementation of Decorator design pattern using C# and Order Manager as an example.
    Here is link to that post.

    http://www.nileshgule.com/2012/07/decorator-design-pattern.html

    Comment by Nilesh Gule — July 4, 2012 @ 4:02 PM | Reply

  11. Thanks for this great post. Its one of the very popular design pattern question in Java. By the here is my example of decorator pattern in Java.

    Comment by java67 — August 30, 2012 @ 7:37 PM | Reply

  12. excellent post! You may also include the nested instantiation of the objects in your team roles example.

    Comment by vassilis — August 31, 2012 @ 7:56 PM | Reply

  13. I just don’t get it, maybe someone could enlight me here. Why the abstract decorator must wrap AND extend the component interface? In your example i see no reason to extend the Employee interface, as the concrete decorators, ie Team Leader, Manager, deal with the roles of the Employees and not with the Employees themselfs… Furthermore, if you what to fire a Manager out of your company you could: Manager.getEmployee().terminate()… Why whould you need Manager.terminate(); when Manager is a role and terminate() refers to an Employee…

    Comment by aviaxisBogdan — October 3, 2012 @ 4:49 PM | Reply

  14. The reason is for been able to write the following:

    new ConcreateDecoratorA(new ConcreateDecoratorB(new ConcreteComponent()));

    This is the actually the purpose of this pattern: to alter in runtime the behavior of a ConcreteComponent via its wrapping by Decorators.

    Hope this helps..

    Cheers

    Comment by vassilis — November 12, 2012 @ 5:05 PM | Reply

  15. I am genuinely glad to glance at this weblog posts which carries
    tons of useful facts, thanks for providing such statistics.

    Comment by fusevision seo — April 28, 2013 @ 5:25 AM | Reply

  16. I think this is a great post. I agree with others that some implementation examples would have been good. When I think of the decorator pattern, I imagine a pattern in which you can add new methods and properties to a class that inherits from the same base class. Like merging the functionality of two classes. That isnt actually what it is, though. If I understand correctly, the decorator allows a class to add functionality to common methods.

    If, for example, TeamMember.terminate() looks like:
    public void terminate()
    {
    this.flipTable();
    }

    and TeamLead.terminate() looks like:
    public void terminate()
    {
    this.fireRestOfTeamOutOfSpite();
    }

    Then if you decorate the TeamMember with TeamLead, calling terminate will first flip a table, then fire the rest of his team out of spite.

    Does that sound right?

    Comment by Brian — May 14, 2013 @ 5:49 PM | Reply

  17. Excellent article. Keep posting such kind of info on your blog.
    Im really impressed by your site.
    Hello there, You have done a great job. I’ll certainly digg it and in my view suggest to my friends. I’m sure they’ll be benefited from this website.

    Comment by Melina — June 3, 2013 @ 10:29 AM | Reply

  18. Please add main () to add clarity, else it feels very incomplete.

    Comment by BJ — July 13, 2013 @ 11:16 AM | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 39 other followers

%d bloggers like this: