People can get very ‘religious’ about design patterns. Folks in this category might think a software application is complete junk unless the code base has n number of patterns baked within. On the other hand, newcomers often think the entire topic is something mysterious or intrinsically difficult. In reality, design patterns are nothing more than a slick, formal way to solve common coding difficulties. The nice thing about classic design patterns in general, is that they are language-agnostic. Once the overall nature of the pattern is understood, developers can add meat to the bones using their language (and platform) of choice.
Numerous design patterns exist in the software world today, and ultimately nothing is preventing you from making your own (if people buy into it or not is another question). Furthermore, there is no ‘master list’ of patterns that all developers agree upon. While this is true, if you pick up any book on the subject, you will find a set of very common patterns most programmers agree are very useful. Many of these patterns were first formalized in the seminal book on the subject, Design Patterns: Elements of Reusable Object-Oriented Software (aka, the Gang of Four [GOF] book; not to be confused with the UK punk band of the same name).
In this post I thought I’d look at one GOF pattern, the decorator pattern, through the eyes of C#. As you will see, C# 2008 and higher provides a very useful shortcut to achieve the same end result (more or less) with minimal fuss and bother.
Breaking Down the Decorator Pattern
The decorator pattern provides a formal way to add new functionality to an existing type, without sub-classing. First question: What is wrong with classical inheritance? In and of itself, nothing is wrong with the good old Is-A relationship. It is very common to derive a new class from an existing base class in order to override a few virtual members, and add a pinch of new functionality.
However, what if the type in question is a sealed class? What if the type is a structure (which is always sealed in the first place)? What if the method you wish to modify was not defined as virtual? In these cases, classical inheritance offers no help. These are just a few simple examples of where the decorator pattern might be useful. The short answer is, when you apply the decorator pattern, you are able to add new functionality to non-extendible types.
Anyway, applying the design pattern often involves the following steps:
- Identify the type you wish to decorate.
- Identify the member (or members) of this type you wish to ‘decorate’ with new functionality.
- Model these members in a .NET interface type, and implement it on the original class.
- Create a brand new class which is responsible for ‘decorating’ the original type, and implement the same shared interface.
- Define a member variable of the original class within the decorator (and provide a constructor to set it).
- Decorate the type with new functionality!
This might sound complicated, but it is really not bad at all. However, one of the annoying aspects of design patterns is that they can often be implemented in numerous manners. For example, the decorator pattern does not require the use of strongly typed interfaces in some situations (you could fallback on classical inheritance to build a intermediate class).
Nevertheless, Let’s see some code.
Applying the Classic Decorator Pattern in C#
Assume the following sealed class, which represents a component you want to tweak:
// This is the existing class // that we want to modify, without sub-classing. public sealed class SimpleTextControl { public string MyMessage { get; set; } public void Display() { Console.WriteLine(MyMessage); } }
Now, lets say you want to spice up the way this class displays the internal text message (maybe with some color, borders, time stamps, etc). Because the class is sealed, you cannot simply create a subclass which overrides the Display() method (and the Display() method is not virtual to begin with!). To continue applying the decorator pattern, you could extract a new interface from SimpleTextControl named ITextDisplay:
public interface ITextDisplay { void Display(); } public sealed class SimpleTextControl : ITextDisplay { ... }
Now onto step four. Here is a decorator class which maintains a reference to a SimpleTextControl object, and injects the new text formatting logic within it’s own implementation of ITextDisplay. The important point to focus on here is that the original object has no idea it is being decorated with surrounding code:
class BoxedMyTextMessage : ITextDisplay { // This is basically a hook to the unaltered object. ITextDisplay itfTextMsg = null; public BoxedMyTextMessage(ITextDisplay oldMsg) { itfTextMsg = oldMsg; } public void Display() { // Add customization and use ref to object. Console.WriteLine("****************************"); itfTextMsg.Display(); Console.WriteLine("****************************"); } }
Here is another decorator class, which adds a time stamp to the message data:
class TimeStamppedMyTextMessage : ITextDisplay { ITextDisplay itfTextMsg = null; public TimeStamppedMyTextMessage(ITextDisplay oldMsg) { itfTextMsg = oldMsg; } public void Display() { itfTextMsg.Display(); Console.WriteLine("-> Message sent at {0}", DateTime.Now); } }
At this point, we can use our decorator classes as so:
static void Main(string[] args) { // Create an instance of the original type // and print the unaltered message. SimpleTextControl tm = new SimpleTextControl(); tm.MyMessage = "Testing....1, 2, 3."; tm.Display(); Console.WriteLine(); // Now show the message decorated with a 'box'. BoxedMyTextMessage btm = new BoxedMyTextMessage(tm); btm.Display(); Console.WriteLine(); // Now with a time stamp! TimeStamppedMyTextMessage tstm = new TimeStamppedMyTextMessage(tm); tstm.Display(); Console.WriteLine(); }
Here is the output of the previous example:
Cool! We have successfully added new functionality (the ability to change how the text is displayed) to an existing class, without subclasses and without method overriding. While the decorator pattern is certainly useful, there are a few problems. First of all, when you use this pattern, you end up with a number of ‘micro’ classes (such BoxedMyTextMessage and TimeStamppedMyTextMessage) which are used in limited circumstances. Second, this classic pattern requires that the original class ( SimpleTextControl in our example) implements the shared interface.
However, if the original class was packaged in a compiled .NET *.dll, the only way to implement this interface would be to dive deep into some gnarly reflection code, create dynamic assemblies, and possibly tinker with some low-level CIL code. As you might agree, most programmer’s would rather *not* bother with this.
Thankfully, .NET 3.5 introduced a new C# language features which allows you to decorate precompiled types. Even better, the amount of required code is far less than what we have seen so far.
Decorating Types using C# Extension Methods
Essentially, extension methods provide a very simple implementation of the formal decorator pattern. The type being extended is not modified in any way, however, via a spoonful of syntactic sugar, this appears to be the case.
Consider the following C# code, which re-creates the previous SimpleTextControl example using extension methods:
// This is the initial class. class SimpleTextControl { public string MyMessage { get; set; } public void Display() { Console.WriteLine(MyMessage); } } // This extension class adds new functionality // to SimpleTextControl. static class TextMessageExtensions { public static void DisplayWithBorder(this SimpleTextControl tm) { Console.WriteLine("****************************"); tm.Display(); Console.WriteLine("****************************"); } public static void DisplayWithTimeStamp(this SimpleTextControl tm) { tm.Display(); Console.WriteLine("-> Message sent at {0}", DateTime.Now); } }
Notice that the ‘extension class’ now takes the role of the previous ‘decorator classes’. Also notice that we no longer need to define a custom interface, as each extension method marks which type it is extending via the first parameter argument. Finally, notice that we have lost a bit of polymorphism, in that each extension method is uniquely named (we could recover this via method overloading provided each extension method offers additional arguments).
Here is some test code with the resulting output:
static void Main(string[] args) { // VB: Dim tm as New MyTextMessage() SimpleTextControl tm = new SimpleTextControl(); tm.MyMessage = "Hello?"; tm.Display(); Console.WriteLine(); tm.DisplayWithBorder(); Console.WriteLine(); tm.DisplayWithTimeStamp(); Console.WriteLine(); }
So there you have it. While extension methods certainly have a syntax which is quite different from the traditional decorator pattern, they can be used for the same end result. Beyond a reduction in typing time, C# extension methods are also very keen in that the original type is truly unmodified, unlike the classic decorator pattern, which typically requires the use of interface implementation.
That wraps up this introductory look at a simple design pattern, and a related C# simplification. If you would like more information on C# patterns, check out the MSDN Patterns and Practices Developer Center.
Happy coding!

24 comments:
wow man, way to keep up!
Nice post !
While I completely agree with you regarding extension methods, the first example (with "classic" C#) does not mirror any situation I have encountered so far.
Let me explain, if you want to add new behaviors to a class and it is sealed, you use the decorator pattern, so far I'm OK with that. But this pattern forces you to alter the class definition and add an interface, you need to have access to the source to do that or, as you said, to modify the IL code, keeping in mind all the problems you can encouter then with digital signatures.
My point is, if you need to have access the source file, why bother implementing a decorator instead of simply removing the sealed keyword, or even directly adding the behavior to the class itself ?
I believe that some functionality is missing from the extension method sample. Part of the decorator design pattern is that the objects become composable, so via example 1, I could write:
new TimeStampedTextMessage(new BoxedTextMessage(new SimpleTextMessage())).Display("Hello World!!");
and get:
**************************
Hello World!!
**************************
-> Message sent at 10:00 AM
As I write new decorators, I can decorate ad infinitum. Providing this kind of functionality does allow new functionality for an existing class without modification, but providing a true decorator requires a shared interface. From the GOF book, "A decorator object's interface must conform to the interface of the component it decorates."
P.S. Does anybody know why don't my arrow keys work in this textbox?
In addition to chris's remark: a true decorater could be passed to a method as an argument (of the ITextDisplay type in this case). This can be done using extension methods, but requires one tweak. Let the extension method consume and return the ITextDisplay interface, and you have a true decorator.
When a new behavior is expected to add to a sealed class, do we really need to hack that sealed class by reflection? I don't think so.
You just need to use another pattern "adapter" to adapter that class into a wrapper class implementing a necessary interface.
Decorators represent a powerful mean to provide the same functionality (actually implemented in the same way) to different classes with eventually different purposes, a kind of "service" you make accessible from a class by simply using its public members (i.e. its interface). It's nothing like implementing an interface (same signature but different code) or defining a base class for inheritance (same members signature and code but also strong inherited class affinity). I won't make it a philosophy matter but I guess extension methods are not just a trick to deal with sealed classes or to keep away from reflection; I think to extension methods as to a service oriented feature.
As a matter of fact the decorator pattern allows the developer to enrich a piece of code with multiple features "chained" without the original caller of the interface method to know that. This is of course most useful if the interface is already there and must not be added. Think of a repository pattern for example, where you can integrate logging, security checks, audits etc. with just a call to an interface method. The chaining can be handled by an IoC container. Since the extensions methods provided here change the signature of the method, the implementation is not hidden from the original caller and thus one of the main features of decorator pattern is not given.
Wow! No offences, but author certainly doesn't understand what is this pattern about :)
P.S. Not going to argue. Just make my point.
hmm, i don't get it, if we have "public sealed class SimpleTextControl" that we want to decorate, then how we can modify it to "public sealed class SimpleTextControl : ITextDisplay"? i thought that subject of decoration can't be modified, that's why we decorating it!
Display method can't change its name for each decorator. The client doesn't need to know which method call for each situation.
You broke the encapsulation, because the client needs to know which method to call. In the correct implementation of decorator pattern, the cliente ALWAYS call the same method, in this case Display method, regardless how many times the original object is decorated.
This is other point: How do you do to decorate an object many times? For instance, a boxed and time stampped SimpleTextControl? Are you going to create other extension method BoxedTimeStamppedMyTextMessage? That is, create methods for each kind of combination? It's just that problem decorator pattern solves.
I think you need to think a little bit out-of-box Microsoft .NET.
The decorator pattern is used to modify an object's interface at runtime (dynamically) so the extension methods are not applicable.
http://www.dofactory.com/Patterns/PatternDecorator.aspx
Further to Chris' and RaimondB's comments above, by altering the sample code slightly, an example of a fully-fledged decorator pattern utilizing extensions can be obtained.
/// Interface from which the text control and all decorators inherit.
interface ITextControl
{
void Display();
}
/// This is the initial class.
sealed class SimpleTextControl : ITextControl
{
public string MyMessage { get; set; }
public void Display()
{
Console.WriteLine(MyMessage);
}
}
/// Base class for all text control decorators.
class TextControlDecorator : ITextControl
{
private Action _decoratorAction;
/// Initializes a new instance of the TextControlDecorator class.
public TextControlDecorator(Action decoratorAction)
{
_decoratorAction = decoratorAction;
}
/// Displays this decorated text control message.
public void Display()
{
_decoratorAction.Invoke();
}
}
// This extension class adds new functionality to ITextControl
static class TextMessageExtensions
{
/// Displays the text control message with border.
public static ITextControl DisplayWithBorder(this ITextControl textControl)
{
return new TextControlDecorator(
delegate()
{
Console.WriteLine("****************************");
textControl.Display();
Console.WriteLine("****************************");
});
}
/// Displays the text control message with a time stamp.
public static ITextControl DisplayWithTimeStamp(this ITextControl textControl)
{
return new TextControlDecorator(
delegate()
{
textControl.Display();
Console.WriteLine("-> Message sent at {0}", DateTime.Now);
});
}
}
Utilizing the code above, the following example demonstrates the decorating functionality.
class Program
{
static void Main(string[] args)
{
SimpleTextControl tm = new SimpleTextControl();
tm.MyMessage = "Hello?";
tm.Display();
Console.WriteLine();
tm.DisplayWithBorder().Display();
Console.WriteLine();
tm.DisplayWithTimeStamp().Display();
Console.WriteLine();
tm.DisplayWithBorder().DisplayWithTimeStamp().Display();
Console.WriteLine();
tm.DisplayWithTimeStamp().DisplayWithBorder().Display();
Console.WriteLine();
Console.ReadKey();
}
}
Output:
Hello?
****************************
Hello?
****************************
Hello?
Message sent at 10:00 AM
****************************
Hello?
****************************
Message sent at 10:00 AM
****************************
Hello?
Message sent at 10:00 AM
****************************
Awesome post Mr. Troelsen. I'm a huge fan of your books/courses. Totally appreciate the blogging. Thank you.
@Mike: As I stated earlier, the big disadvantage of your example code is that the method calls are not transparent to the original caller, which is somehow contradictory (at least in my opinion) to the decorator pattern. You need to explicitly call the methods e.g. :
tm.DisplayWithBorder().Display()
In a true decorator pattern you want the implementation to be extended by chaining decorators so that you just call:
ITextControl c = new BorderedTextControl(new SimpleTextControl()); // the initialization should be done by an IoC container for example
c.Display();
@Johannes: how is new BorderedTextControl(new SimpleTextControl()); not explicitly constructing the different classes?
With the extension methods you no longer need to instantiate the BorderedTextControl where tm is the SimpleTextControl.
tm.DisplayWithBorder().Display();
@Michael,
Johannes point is that somewhere else along the line, someone could have modified the behavoir of the display method by decorating the control. He noted that the initialization should be done by an Inversion of Control, and not right before the call to Display.
So it would be called as
public void Method(ITextControl c)
{
// Some Code
c.Display()
// Some Code
}
So the caller of your function can modify the bevaior of the control all they want and you don't need to know about the changes. This is useful in cases where user interaction (GUI events) can wrap decorators around the base object before the final command is given. then it is not hard coded at all but generated at run time.
If you use your extension methods, then you always have to call DisplayWithBorder() before Display to get that behavior, which requires a change in the code ever place you want the behavior. This would be harder to accomplish at runtime.
Obviously the implementation of the Decorator pattern was a bit skewed, but the discussion that followed is wonderful.
Thanks for the post.
MIA: Dynamic Composition Capability
This is the whole point of the Decorator.
While Mr. Troelsen's implementation is interesting, it doesn't decorate. The key feature of the Decorator Pattern is for a client to dynamically compose an object with any pieces the client sees fit. This is the Decorated object. The client hands that decorated object to the server which then runs that object. The server is no wiser as what to the client did. Nor does it care. Everybody is happy.
Mr. Troelsen would have us create a bunch of static methods, and I double emphasize static.
So, if there are 4 different things that can be done, we quickly get into combinatorial explsosion..
AB, AC, AD, BC, BD, CD , etc. + a whole bunch of methods for the non-commuting case. These would all be implemented as a different static extension method.
The client code to pick the right extension method is a big ugly switch statement.
In conclusion, although the implementation methodology via .NET extensions sounds cute, I would strongly recommend sticking to the orignal Decorator pattern impelmentation.
Extension methods serve their purpose. That purpose is not to implement the decorator pattern.
I agree with Bryan's summation (ang thanks).
Personally, I see and use extensions as a snippet library, substitutes for inline methods, and variations on provided methods not suited to decoration. Respective examples:
public static string toFormattedString(this Exception source){
(no copy-paste = this example is too big) :(
}
public static byte[] getBytes(this string source){
return Encoding.UTF8.GetBytes(source);
}
public static void myInvoke[T](this T source, Action action) where T : Control{
if(source.Created && !source.IsDisposed){
source.Invoke(action);
} else{
action.Invoke();
}
}
my comment was too long but a response can be found on my blog:
Implementing the Decorator Pattern
Post a Comment
Note: Only a member of this blog may post a comment.