The Decorator pattern is intended to give you a way to extend the behavior of an object or to dynamically compose an object’s behavior at runtime.
The Decorator Pattern is used for adding additional functionality to a particular object as opposed to a class of objects. It is easy to add functionality to an entire class of objects by subclassing an object, but it is impossible to extend a single object this way. With the Decorator Pattern, you can add functionality to a single object and leave others like it unmodified.
Decorators provide a flexible alternative to subclassing for extending functionality.
Code examples (click to enlarge/collapse):
-
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758class Client{static void Main(){Console.WriteLine("Concrete Component -> Message");Component component = new ConcreteComponent();component.Operation();Console.WriteLine();Console.WriteLine();Console.WriteLine("Decorator -> Simple decoration");Decorator decorator = new ConcreteDecorator();decorator.SetComponent(component);decorator.Operation();Console.ReadKey();}}public class Decorator : Component{public Component component;public void SetComponent(Component component){this.component = component;}public override void Operation(){if (component != null){component.Operation();}}}public class ConcreteDecorator : Decorator{public override void Operation(){Console.WriteLine("*****************");Console.Write("* ");base.Operation();Console.WriteLine(" *");Console.WriteLine("*****************");}}public abstract class Component{public abstract void Operation();}public class ConcreteComponent : Component{public override void Operation(){Console.Write("Hello, world!");}}
-
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253class Client{static void Main(){Message msg = new TextMessage();msg.Value = "Hello, world.";Formatter formatter = new XmlFormatter();formatter.LoadMessage(msg);string result = formatter.ToString();Console.WriteLine("Formatted message: {0}", result);Console.ReadKey();}}public class Formatter : Message{public Message component;public void LoadMessage(Message component){this.component = component;}public override string ToString(){if (component != null){return component.ToString();}else return null;}}public class XmlFormatter : Formatter{public override string ToString(){return string.Format("{0}", base.ToString());}}public abstract class Message{public string Value;public new abstract string ToString();}public class TextMessage : Message{public override string ToString(){return this.Value;}}
This post is part of my series on the foundational design patterns in C#. In this series we explore the ancient design patterns and their use in real-world programming situations of today. In these series of posts we explore each pattern and look at simplified real-world C# code that implements the pattern.