[tweetmeme source=”aabdulmoniem” only_single=false]

We have discussed in our previous post the decorator pattern’s role, and giving a very detailed illustration about it. Also, we have discussed its design varieties and clarified when to use each design and why.

Today, we will complete our discussion about decorator pattern. We will talk deeply about different examples from the real world cases to give you more deep understanding of this pattern. Also, we will discuss when to use this pattern in real world situations.

We will demonstrate first a simple example and then move on to a more complicated ones and more variations.

1 – Example: Use Case Diagram Tool

Use case diagram is one of the fundamental diagrams of the unified modeling language (UML). We use the use case diagrams to describe all the use cases a user can interact with within an application.

Here, we will start to build a simple (Really, it is a very simple, just for demonstrations purposes) use case diagram tool.

If we look more thoughtfully into the available shapes that can be drawn in a use case diagram, we will find them to be 3 main shapes:

Actors. Use cases. Arrows (which represent relationships between actors, or between use cases or between actors and use cases).

But a more deep look, we will find that each shape has a different look in a different situations.

As described in the following diagram, some of the variations that could be applied to any shape during drawing process of use case diagrams:

The challenge here that we want to build an application that covers all the variations available and with an ability to add more shapes in futures in case of any updates happens to UML.

Here comes the magic of the decorator pattern. Let’s get started:

Analyzing the last diagram shows us that we have 3 main shapes with different variations. Variations means here decorators which can be applied to different shapes to show us the right final shape.

More analyzing, we are noticing that we have some kind of hybrid decorators like for example, dotted line with a tag. In fact, they are two decorators tag decorator and dotted line decorator.

Let’s first start with one shape and then we will elaborate on this.

IShape interface and Actor class:

IShape Interface:

public interface IShape { Bitmap Draw(); }

Actor Class:

public class Actor : IShape { public Bitmap Draw() { Bitmap image = new Bitmap(200, 200); using (Graphics graphics = Graphics.FromImage(image)) { using (Pen blackPen = new Pen(Brushes.Black)) { // Drawing head graphics.DrawEllipse(blackPen, 100, 20, 20, 20); // Drawing backbone graphics.DrawLine(blackPen, 110, 40, 110, 80); // Drawing arms graphics.DrawLine(blackPen, 110, 55, 130, 55); graphics.DrawLine(blackPen, 110, 55, 90, 55); // Drawing legs graphics.DrawLine(blackPen, 110, 80, 130, 100); graphics.DrawLine(blackPen, 110, 80, 90, 100); } } return image; } }

If we try now to use this class with a windows forms application in .NET for example you will write just like the following code after dragging a picture box into the form:

Actor actor = new Actor(); pictureBox1.Image = actor.Draw();

Run the project, you will see:

Now we need to add some sugar, so let’s add a decorator called TagDecorator which will be responsible for adding tags (titles) to any shape.

Here is the class diagram (following the guidelines of decorator patterns):

TagDecorator Class:

public class TagDecorator : IShape { private IShape _shape; private string _tag; public TagDecorator(IShape shape, string tag) { _shape = shape; _tag = tag; } public Bitmap Draw() { // Getting the actor shape without tags Bitmap image = _shape.Draw(); // Writing the tag under the actor shape using (Graphics grahpics = Graphics.FromImage(image)) { grahpics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; StringFormat stringFormat = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; grahpics.DrawString(_tag, new Font("Times New Roman", 12), Brushes.Black, new RectangleF(10, 110, 200, 20), stringFormat); } return image; } }

Let’s try to draw this decorated actor to the form. So we will write this code:

Actor actor = new Actor(); TagDecorator actorTag = new TagDecorator(actor, "User"); pictureBox1.Image = actorTag.Draw();

And see the output:

Now let’s make things more complicated, I will just give you the concepts and let you try to implement them.

What if we want to add more shapes, simply we will use the following diagram:

What about more decorators?!

Go, and try to build you own diagramming tool.

2 – Real World Examples

Now we will demonstrate some real world examples may be we are using in a daily basis but we don’t know.

In a very good article by Rob Pierry, he discussed when a decorator pattern has been used within .NET. He Said:

“Any useful executable program involves either reading input, writing output, or both. Regardless of the source of the data being read or written, it can be treated abstractly as a sequence of bytes. .NET uses the System.IO.Stream class to represent this abstraction. Whether the data involves characters in a text file, TCP/IP network traffic, or something else entirely, chances are you will have access to it via a Stream. Since the class for working with file data (FileStream) and the class for working with network traffic (NetworkStream) both inherit from Stream, you can easily write code that processes the data independent of its origins. Here’s a method for printing out some bytes from a Stream to the console:

public static void PrintBytes(Stream s) { int b; while((b = fs.ReadByte()) >= 0) { Console.Write(b + " "); } }

Reading a single byte at a time is typically not the most efficient way to access a stream. For example, hard drives are capable of (and optimized for) reading continuous blocks of data from the disk in a big chunk. If you know you are going to be reading several characters, it is better to read a chunk from the disk all at once and then consume the chunk from memory byte by byte. The Framework includes the BufferedStream class for doing just that. The constructor for BufferedStream takes as the parameter whatever stream you would like buffered access to. BufferedStream overrides the main methods of Stream, such as Read and Write, to provide more functionality. Since it is still a child class of Stream, you can use it the same as any other Stream (note that FileStream includes its own buffering capabilities). Similarly, you can use System.Security.Cryptography.CryptoStream to encrypt and decrypt Streams on the fly, without the rest of the application needing to know anything more than the fact that it is a Stream.

This ability to dynamically attach new functionality to objects transparently using composition is an example of the Decorator pattern”.

This is valid also for Java developers as well as far as I know in java.io namespace.

Let’s also demonstrate a more general real examples:

Here are four ways the Decorator pattern is used in the real world (Excerpt from C# 3.0 Design patterns):

As our small example illustrated, the Decorator pattern fits well in the graphics world. It is equally at home with video and sound; for instance, video streaming can be compressed at different rates, and sound can be input to a simultaneous translation service.

At a more mundane level, decorators abound in the I/O APIs of C# as illustrated.

In today’s world of mobile devices, web browsers and other mobile applications thrive on the Decorator pattern. They can create display objects suitable for smaller screens that include scroll bars and exclude banners that would be standard on desktop display browsers, for example.

The Decorator pattern is so useful that there are now actual Decorator classes in .NET 3.0. The one in System.Windows.Controls “provides a base class for elements that apply effects onto or around a single child element, such as Border or Viewbox.”

3 – When to use?

When you have:

An existing component class that may be unavailable for subclassing.

Or When you want to:

Attach additional state or behavior to an object dynamically.

Make changes to some objects in a class without affecting others.

Avoid subclassing because too many classes could result.

4 – Finally

At last, we have finished demonstrating this pattern. Our next one is Proxy pattern. So, be with us 🙂