{"id":978,"date":"2012-04-16T18:35:04","date_gmt":"2012-04-16T23:35:04","guid":{"rendered":"https:\/\/daedtech.wpenginepowered.com\/?p=978"},"modified":"2015-05-27T15:57:00","modified_gmt":"2015-05-27T20:57:00","slug":"decorator","status":"publish","type":"post","link":"https:\/\/daedtech.com\/decorator\/","title":{"rendered":"Decorator"},"content":{"rendered":"<h3>Quick Information\/Overview<\/h3>\n<table>\n<tbody>\n<tr>\n<td>Pattern Type<\/td>\n<td>Structural<\/td>\n<\/tr>\n<tr>\n<td>Applicable Language\/Framework<\/td>\n<td>Agnostic OOP<\/td>\n<\/tr>\n<tr>\n<td>Pattern Source<\/td>\n<td><a href=\"http:\/\/en.wikipedia.org\/wiki\/Design_Patterns\">Gang of Four<\/a><\/td>\n<\/tr>\n<tr>\n<td>Difficulty<\/td>\n<td>Easy<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><img decoding=\"async\" src=\"https:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif\" alt=\"\" \/><\/p>\n<h3>Up Front Definitions<\/h3>\n<ol>\n<li><strong>Decorator:<\/strong>\u00a0An object that is both an inherits from and operates on another object.<\/li>\n<li><strong>Component:<\/strong> Abstract target base class (or interface) of the decorator pattern.<\/li>\n<li><strong>Target: <\/strong>For the purposes of this post, I use this term interchangeably with Component.<\/li>\n<\/ol>\n<h3>The Problem<\/h3>\n<p>Let&#8217;s say that you have to model employees at a company, and all employees have a name, an hourly wage, and a bio that describes them. Furthermore, these items are going to be determined by the type of employee that each employee is (they can be Workers, Managers, or Executives for now, but there might be more later). Since this begs for an extensible, polymorphic structure, you create the following class structure and program to take it for a test drive:<br \/>\n<!--more--><\/p>\n<pre lang=\"C#\">\r\npublic abstract class Employee\r\n{\r\n    public string Name { get; protected set; }\r\n\r\n    public double HourlyWage { get; protected set; }\r\n\r\n    public string EmployeeBio { get; protected set; }\r\n\r\n    protected Employee(string name, double hourlyWage, string bio)\r\n    {\r\n        HourlyWage = hourlyWage;\r\n        Name = name;\r\n        EmployeeBio = bio;\r\n    }\r\n}\r\n\r\npublic class Worker : Employee\r\n{\r\n    public Worker(string name) : base(name, 12.5, \"Rank and File\") { }\r\n}\r\n\r\npublic class Manager : Employee\r\n{\r\n    public Manager(string name) : base(name, 25.0, \"Line Manager\") { }\r\n}\r\n\r\npublic class Executive : Employee\r\n{\r\n    public Executive(string name) : base(name, 50.0, \"Bigwig\") { }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        myEmployees.Add(new Worker(\"Jim Halpert\"));\r\n        myEmployees.Add(new Manager(\"Michael Scott\"));\r\n        myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1}, makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Simple enough. This is nice and clean because later, if we want to add a new type of employee (maybe Toby from HR), we can just create a new type of employee through inheritance, and the print function will hum happily along. This is classic <a href=\"http:\/\/msdn.microsoft.com\/en-us\/magazine\/cc546578.aspx\">Open\/Closed Principle<\/a> stuff. Different types of employees define their own attributes, and there are no ugly enums called &#8220;EmployeeType&#8221; &#8212; life is good.<\/p>\n<p>Now, let&#8217;s say that an industrious project manager gets wind of the rave reviews your office modeling program has gotten for its usability and clean design and decides to hitch his wagon to your effort. You get a request coming in that employees be able to be distinguished as &#8220;high performers&#8221;. Any employee with the &#8220;high performer&#8221; designation should be paid 10% more than non-high performer counterparts, and this recognition should be reflected in the employee&#8217;s bio. So, you change the code to look like this:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class Employee\r\n{\r\n    public string Name { get; protected set; }\r\n\r\n    public double HourlyWage { get; protected set; }\r\n\r\n    public string EmployeeBio { get; protected set; }\r\n\r\n    protected Employee(string name, double hourlyWage, string bio, bool isHighPerformer = false)\r\n    {\r\n        HourlyWage = hourlyWage;\r\n        Name = name;\r\n        EmployeeBio = bio;\r\n        if (isHighPerformer)\r\n        {\r\n            HourlyWage *= 1.10;\r\n            EmployeeBio = EmployeeBio + \", High Performer\";\r\n        }\r\n    }\r\n}\r\n\r\npublic class Worker : Employee\r\n{\r\n    public Worker(string name, bool isHighPerformer = false) : base(name, 12.5, \"Rank and File\", isHighPerformer) { }\r\n}\r\n\r\npublic class Manager : Employee\r\n{\r\n    public Manager(string name, bool isHighPerformer = false) : base(name, 25.0, \"Line Manager\", isHighPerformer) { }\r\n}\r\n\r\npublic class Executive : Employee\r\n{\r\n    public Executive(string name, bool isHighPerformer = false) : base(name, 50.0, \"Bigwig\", isHighPerformer) { }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        myEmployees.Add(new Worker(\"Jim Halpert\", true));\r\n        myEmployees.Add(new Manager(\"Michael Scott\"));\r\n        myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1}, makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Hmmm&#8230; polymorphic structure still looks good, and the optional parameter even allows you to implement this functionality as a non-breaking change for client code, but the constructors are starting to get a little noisy and unfocused. It&#8217;s also not necessarily awesome that you had to touch every class constructor in the polymorphic structure, but whatever, project management is happy and hopefully they don&#8217;t ask for more stuff like that.<\/p>\n<p>And, turns out they don&#8217;t. Instead, they want to be able to record the fact that some employees are members of the corporate &#8220;safety team&#8221;, responsible for knowing how fire extinguishers work and counting people during fire drills and whatnot. So, during the normal print, safety team membership should be reflected in the bio, but it should also be possible to see what a safety team member&#8217;s team responsibility is.<\/p>\n<p>Here we have a classic inheritance situation&#8230; sort of. Safety team members are still normal employees (meaning any safety team member must be worker, manager or exec), so they can&#8217;t inherit from the abstract base employee class. And, it doesn&#8217;t make sense to add safety team information and implementation to any existing classes, since none of them necessarily represent safety team members. So, you suppose they&#8217;ll just have to inherit from the three classes we&#8217;ve defined so far, like this:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class Employee\r\n{\r\n    public string Name { get; protected set; }\r\n\r\n    public double HourlyWage { get; protected set; }\r\n\r\n    public string EmployeeBio { get; protected set; }\r\n\r\n    protected Employee(string name, double hourlyWage, string bio, bool isHighPerformer = false)\r\n    {\r\n        HourlyWage = hourlyWage;\r\n        Name = name;\r\n        EmployeeBio = bio;\r\n        if (isHighPerformer)\r\n        {\r\n            HourlyWage *= 1.10;\r\n            EmployeeBio = EmployeeBio + \", High Performer\";\r\n        }\r\n    }\r\n}\r\n\r\npublic class Worker : Employee\r\n{\r\n    public Worker(string name, bool isHighPerformer = false) : base(name, 12.5, \"Rank and File\", isHighPerformer) { }\r\n}\r\n\r\npublic class SafetyTeamWorker : Worker\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamWorker(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\npublic class Manager : Employee\r\n{\r\n    public Manager(string name, bool isHighPerformer = false) : base(name, 25.0, \"Line Manager\", isHighPerformer) { }\r\n}\r\n\r\npublic class SafetyTeamManager : Manager\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamManager(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\npublic class Executive : Employee\r\n{\r\n    public Executive(string name, bool isHighPerformer = false) : base(name, 50.0, \"Bigwig\", isHighPerformer) { }\r\n}\r\n\r\npublic class SafetyTeamExecutive : Executive\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamExecutive(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        myEmployees.Add(new Worker(\"Jim Halpert\", true));\r\n        myEmployees.Add(new SafetyTeamManager(\"Michael Scott\"));\r\n        myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1}, makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Uh, oh. This is starting to smell. You&#8217;re not thrilled about creating three classes when what you really wanted was one class, and you&#8217;re <em>really<\/em> not thrilled about the fact that the three classes are copy and paste jobs of one another. But, no time for all that clean code claptrap now, you&#8217;re getting more requirements in from the project manager and you&#8217;ve got to get things <em>done<\/em>. They system also has to be able to track whether employees are on the softball team and, if so, what position they play. So that means, another three copy and paste classes. Except, wait a minute, safety team members can be softball players too. So, we really need to add another 6 copy and paste classes, bringing the total to 9 copies and 3 that we started with:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class Employee\r\n{\r\n    public string Name { get; protected set; }\r\n\r\n    public double HourlyWage { get; protected set; }\r\n\r\n    public string EmployeeBio { get; protected set; }\r\n\r\n    protected Employee(string name, double hourlyWage, string bio, bool isHighPerformer = false)\r\n    {\r\n        HourlyWage = hourlyWage;\r\n        Name = name;\r\n        EmployeeBio = bio;\r\n        if (isHighPerformer)\r\n        {\r\n            HourlyWage *= 1.10;\r\n            EmployeeBio = EmployeeBio + \", High Performer\";\r\n        }\r\n    }\r\n}\r\n\r\npublic class Worker : Employee\r\n{\r\n    public Worker(string name, bool isHighPerformer = false) : base(name, 12.5, \"Rank and File\", isHighPerformer) { }\r\n}\r\n\r\npublic class SoftballPlayingWorker : Worker\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingWorker(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\npublic class SafetyTeamWorker : Worker\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamWorker(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\npublic class SoftballPlayingSafetyTeamWorker : SafetyTeamWorker\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingSafetyTeamWorker(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\npublic class Manager : Employee\r\n{\r\n    public Manager(string name, bool isHighPerformer = false) : base(name, 25.0, \"Line Manager\", isHighPerformer) { }\r\n}\r\n\r\npublic class SoftballPlayingManager : Manager\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingManager(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\npublic class SafetyTeamManager : Manager\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamManager(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\npublic class SoftballPlayingSafetyTeamManager : SafetyTeamManager\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingSafetyTeamManager(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\npublic class Executive : Employee\r\n{\r\n    public Executive(string name, bool isHighPerformer = false) : base(name, 50.0, \"Bigwig\", isHighPerformer) { }\r\n}\r\n\r\npublic class SoftballPlayingExecutive : Executive\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingExecutive(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\npublic class SafetyTeamExecutive : Executive\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamExecutive(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Safety Team Member\";\r\n    }\r\n}\r\n\r\npublic class SoftballPlayingSafetyTeamExecutive : SafetyTeamExecutive\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayingSafetyTeamExecutive(string name, bool isHighPerformer = false) : base(name, isHighPerformer)\r\n    {\r\n        EmployeeBio += \", Softball Player\";\r\n    }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        myEmployees.Add(new Worker(\"Jim Halpert\", true));\r\n        myEmployees.Add(new SafetyTeamManager(\"Michael Scott\"));\r\n        myEmployees.Add(new SoftballPlayingSafetyTeamExecutive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1}, makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Suddenly, you&#8217;ve got a train-wreck on your hands. After you track down a few hard-to-fix defects that resulted from the wrong inheritance scheme when you forgot to change &#8220;Worker&#8221; to &#8220;Manager&#8221; in one of your copy-paste implementations, the project manager tells you that there&#8217;s no time for refactoring because now you need to be able to who who is on the Party Planning Committee and who is a member of the Finer Things Club. Your 12 classes just became 36 and then 108.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/daedtech.com\/pics\/goggles.jpg\" alt=\"\" \/><\/p>\n<p>The only option at this point is clearly to write a program that can automate generating this code for you. That, or retire.<\/p>\n<h3>So, What to Do?<\/h3>\n<p>As is often the case in this series of posts, the important thing is to retrace our steps and figure out where things went off the rails. And, as is even more often the case, our problems started as soon as we started duplicating code, and they got worse the more egregiously we did it. So, where do we go from here? It&#8217;s simpler in this post than in some of the others &#8212; let&#8217;s start by deleting all of these misguided inheritors and revert to the state we were in immediately after defining our optional &#8220;isHighEarner&#8221; parameter (we&#8217;ll get to that later).<\/p>\n<p>Now, let&#8217;s add a class called &#8220;EmployeDecorator&#8221;. It will inherit from Employee and be abstract. If you&#8217;ll recall, when implementing the safety team requirement, we dismissed the possibility of safety team inheriting from Employee directly because safety team members also needed to be Workers, Managers, or Executives, but we&#8217;re going to introduce a way around that problem:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class EmployeeDecorator : Employee\r\n{\r\n    private readonly Employee _target;\r\n    protected Employee Target { get { return _target; } }\r\n\r\n    public EmployeeDecorator(Employee target)\r\n    {\r\n        _target = target;\r\n        Name = target.Name;\r\n        HourlyWage = target.HourlyWage;\r\n        EmployeeBio = EmployeeBio;\r\n    }\r\n}\r\n<\/pre>\n<p>Notice that this decorator object curiously <em>both inherits from and wraps<\/em> Employee, and proceeds to seed its own properties with those of the employee. This allows the decorator to look to clients as though it <em>is<\/em> the object its wrapping. This has some powerful ramifications, as we can see here:<\/p>\n<pre lang=\"C#\">\r\npublic class SafetyTeamMember : EmployeeDecorator\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamMember(Employee target) : base(target)\r\n    {\r\n        EmployeeBio += \"Safety Team Member \";\r\n    }\r\n}\r\n<\/pre>\n<p>Now, we can add safety team member functionality to an employee simply by taking an employee and injecting it into the constructor of the concrete decorator. As we do this, we trust the decorator to apply the appropriate modifications to the employee and expose the properties that we would demand of the employee. So, in this case decorator adds bio information and when we query its bio, we get the employee&#8217;s information plus the &#8220;decoration&#8221; of the addition to the bio. On top of that, we can set this object&#8217;s &#8220;Safety Description&#8221;. In effect, we&#8217;re extending the functionality of an object without inheriting directly from it. The common ancestor is, however necessary, as this is what gives us access to the protected members of employee. Here is the client instantiation logic:<\/p>\n<pre lang=\"C#\">\r\nstatic void Main(string[] args)\r\n{\r\n    var myEmployees = new List();\r\n    myEmployees.Add(new Worker(\"Jim Halpert\", true));\r\n    var myManager = new Manager(\"Michael Scott\");\r\n    myEmployees.Add(new SafetyTeamMember(myManager));\r\n    myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n    PrintAllEmployees(myEmployees);\r\n}\r\n<\/pre>\n<p>And this results in the same printed information. Now, let&#8217;s implement our softball player requirement and set Michael Scott up as both a softball player and a safety team member.<\/p>\n<pre lang=\"C#\">\r\npublic class SoftballPlayer : EmployeeDecorator\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayer(Employee target) : base(target)\r\n    {\r\n        EmployeeBio += \"Softball Player, \";\r\n    }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        myEmployees.Add(new Worker(\"Jim Halpert\", true));\r\n        Employee myManager = new Manager(\"Michael Scott\");\r\n        myManager = new SoftballPlayer(myManager);\r\n        myEmployees.Add(new SafetyTeamMember(myManager));\r\n        myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1} makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Now, Michael is a real Rennaisance Man, and it only took 3 extra classes rather than 12. And, that number will raise to 5, rather than 108, with the next set of project management requirements. So, we&#8217;re setting pretty, but we can do even better &#8212; we can refactor the higher performer functionality to be part of another decorator as well, to achieve this finished product:<\/p>\n<pre lang=\"C#\">\r\npublic abstract class Employee\r\n{\r\n    public string Name { get; protected set; }\r\n\r\n    public double HourlyWage { get; protected set; }\r\n\r\n    public string EmployeeBio { get; protected set; }\r\n\r\n    protected Employee() { }\r\n\r\n    protected Employee(string name, double hourlyWage, string bio)\r\n    {\r\n        HourlyWage = hourlyWage;\r\n        Name = name;\r\n        EmployeeBio = bio;\r\n    }\r\n}\r\n\r\npublic class Worker : Employee\r\n{\r\n    public Worker(string name) : base(name, 12.5, \"Rank and File, \") { }\r\n}\r\n\r\npublic class Manager : Employee\r\n{\r\n    public Manager(string name) : base(name, 25.0, \"Line Manager, \") { }\r\n}\r\n\r\npublic class Executive : Employee\r\n{\r\n    public Executive(string name) : base(name, 50.0, \"Bigwig, \") { }\r\n}\r\n\r\npublic abstract class EmployeeDecorator : Employee\r\n{\r\n    private readonly Employee _target;\r\n    protected Employee Target { get { return _target; } }\r\n\r\n    public EmployeeDecorator(Employee target)\r\n    {\r\n        _target = target;\r\n        Name = target.Name;\r\n        HourlyWage = target.HourlyWage;\r\n        EmployeeBio = target.EmployeeBio;\r\n    }\r\n}\r\n\r\npublic class SafetyTeamMember : EmployeeDecorator\r\n{\r\n    public string SafetyDescription { get; set; }\r\n\r\n    public SafetyTeamMember(Employee target) : base(target)\r\n    {\r\n        EmployeeBio += \"Safety Team Member, \";\r\n    }\r\n}\r\n\r\npublic class SoftballPlayer : EmployeeDecorator\r\n{\r\n    public string Position { get; set; }\r\n\r\n    public SoftballPlayer(Employee target) : base(target)\r\n    {\r\n        EmployeeBio += \"Softball Player, \";\r\n    }\r\n}\r\n\r\npublic class HighPerformer : EmployeeDecorator\r\n{\r\n    public HighPerformer(Employee target) : base(target)\r\n    {\r\n        EmployeeBio += \" High Performer,\";\r\n        HourlyWage *= 1.10;\r\n    }\r\n}\r\n\r\nclass Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        var myEmployees = new List();\r\n        Employee myWorker = new Worker(\"Jim Halpert\");\r\n        myEmployees.Add(new HighPerformer(myWorker));\r\n        Employee myManager = new Manager(\"Michael Scott\");\r\n        myManager = new SoftballPlayer(myManager);\r\n        myEmployees.Add(new SafetyTeamMember(myManager));\r\n        myEmployees.Add(new Executive(\"Jan Levenson\"));\r\n\r\n        PrintAllEmployees(myEmployees);\r\n    }\r\n\r\n    private static void PrintAllEmployees(ListmyEmployees)\r\n    {\r\n        foreach (var myEmployee in myEmployees)\r\n        {\r\n            Console.WriteLine(String.Format(\"{0}, {1} makes {2} per hour.\", myEmployee.Name, myEmployee.EmployeeBio, myEmployee.HourlyWage));\r\n        }\r\n        Console.ReadLine();\r\n    }\r\n}\r\n<\/pre>\n<p>Now, that weird extra parameter is gone &#8212; &#8220;high performance&#8221; is now something added to employees rather than ingrained. And, the high performance decorator illustrates nicely that decorators can serve either or both of two purposes: extending functionality and\/or modifying the target (&#8220;component&#8221;).<\/p>\n<h3>A More Official Explanation<\/h3>\n<p>Turning once again to <a href=\"http:\/\/www.dofactory.com\/Patterns\/PatternDecorator.aspx\">dofactory<\/a> (UML diagram image came from here as well), a more formal definition of the Decorator Pattern is to:<\/p>\n<blockquote><p>Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. <\/p><\/blockquote>\n<p>The key thing to note in our process or refactoring toward the Decorator pattern is that we were defining a scheme whereby employees could be given ancillary responsibilities without changing their fundamental makeup.  In our example, all employees have a wage, name, and bio, but not all employees are safety team members, high earners, etc.  The Decorator pattern allows us to reflect this reality by attaching these ancillary responsibilities in <em>ad hoc<\/em> fashion, and without adding any properties to the Employee class or sub-classes that may not be used.<\/p>\n<p>The Decorator Pattern is a means for extending a class&#8217;s functionality without either modifying that class or inheriting from that class.  It takes advantage of the nature of inheritance to gain access to the class&#8217;s protected members in order to expose new state modifying behavior to its clients.<\/p>\n<h3>Other Quick Examples<\/h3>\n<p>Here are some other places that the Decorator pattern is used:<\/p>\n<ol>\n<li>GUI scenarios where a GUI component may have many tangentially related properties (e.g. a window may have scrollbars, which are not really intrinsic to the Window itself, but handy to be able to add)<\/li>\n<li>&#8220;Stream&#8221; objects (Java) that add behavior to application I\/O by decorating the basic I\/O implementation.<\/li>\n<li>Anywhere that there is a significant desire to extend the main functionality of an object hierarchy, such as a series of customizations to an invoice or order object.<\/li>\n<\/ol>\n<h3>A Good Fit \u2013 When to Use<\/h3>\n<p>The Decorator pattern makes sense to use if you have an object hierarchy that you want to keep pretty much as-is, but you want to add some custom, kind of one-off behavior to it.  In the example above, we like the employee hierarchy and don&#8217;t really want to clutter it up, but we would like to capture the fact that employees can also occasionally have other, custom behaviors.  This makes senses if we extend the example to the GUI components like windows as well.  We may sometimes want Windows to have scrollbars, but that doesn&#8217;t mean there is a need to have ScrollbarWindow, HorizontalScrollbarWindow, VerticalScrollbarWindow, BothScrollbarWindow, etc for every conceivable type of window.<\/p>\n<p>In fact, that type of combinatorial explosion of types is another definite call for the Decorator pattern.  The pattern is a good fit for adding one-off behavior to object hierarchies, but it&#8217;s pretty much a <em>must<\/em> if you find yourself in a situation where simple inheritance would mean defining something like n! new classes for each behavior you want.  If you find yourself saying &#8220;well, I&#8217;d need a HorizontalScrollbarDialogWindow and a HorizontalScrollbarNormalWindow, and a VerticalScrollbarDialogWindow, etc&#8221;, stop and give serious though to Decorator.<\/p>\n<h3>Square Peg, Round Hole \u2013 When Not to Use<\/h3>\n<p>This pattern may not be necessary for certain scenarios.  Consider our working example above, and forget all of the other &#8220;hats&#8221; employees can wear but the Safety Team.  If we knew this was the only other thing to be modeled, it might be worth having a SafetyTeam object that stored a collection of employee objects.  This would allow all members of the safety team to be identified.  Granted, you wouldn&#8217;t get it as part of the employee bio, but perhaps that could be achieved in another way.  Point is, Decorator may be overkill if there isn&#8217;t much decoration going on.<\/p>\n<p>Decorator also may not fit if you have no combinatorial explosion and significant control over and flexibility with the object hierarchy.  It&#8217;s not an option that I personally like, and I think it&#8217;s a bit clumsy, but we could have achieved some of the functionality above with the Employee base class having properties for IsSafetyTeamMember and IsHighPerformer and IsSoftballPlayer.  If we knew that we were limited to these three (and thus not <a href=\"https:\/\/daedtech.com\/the-outhouse-anti-pattern\" title=\"The Outhouse Anti Pattern\">building an outhouse<\/a>), this rigid design would suffice.  <\/p>\n<p>So, the point is that having and dealing with some existing object hierarchy does not automatically mean that the Decorator pattern is a good fit.  It introduces some design complexity and potential understanding issues, so it should be introduced to solve a real, current problem, rather than a hypothetical future one.<\/p>\n<h3>So What? Why is this Better?<\/h3>\n<p>As demonstrated above, Decorator makes code a lot cleaner in situations where responsibilities need to be added in ad-hoc fashion to an existing object hierarchy.  This is particularly true when the new responsibilities are somewhat tangential to the main hierarchy.  Using this pattern allows you to manipulate protected members of the class in question without sub-classing it directly, and to present an object to clients that looks uniform and hides the trickery that you&#8217;ve pulled.<\/p>\n<p>Your inheritance hierarchies when using this pattern will remain both shallower and narrower, which definitely facilitates better understanding of code.  But, you won&#8217;t have to sacrifice any flexibility to get this more manageable inheritance tree.  And, in the end, you&#8217;ll save yourself the ugliness of getting into a situation where the number of classes you have are described in terms of factorial.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Quick Information\/Overview Pattern Type Structural Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Easy Up Front Definitions Decorator:\u00a0An object that is both an inherits from and operates on another object. Component: Abstract target base class (or interface) of the decorator pattern. Target: For the purposes of this post, I use this term interchangeably&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"categories":[25],"tags":[10],"class_list":["post-978","post","type-post","status-publish","format-standard","hentry","category-design-patterns","tag-c"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Decorator - DaedTech<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/daedtech.com\/decorator\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:title\" content=\"Decorator - DaedTech\" \/>\n<meta name=\"twitter:description\" content=\"Quick Information\/Overview Pattern Type Structural Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Easy Up Front Definitions Decorator:\u00a0An object that is both an inherits from and operates on another object. Component: Abstract target base class (or interface) of the decorator pattern. Target: For the purposes of this post, I use this term interchangeably...\" \/>\n<meta name=\"twitter:image\" content=\"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Erik Dietrich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/\"},\"author\":{\"name\":\"Erik Dietrich\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/person\\\/3dae63e91a0fa60c8051a2171fa687d2\"},\"headline\":\"Decorator\",\"datePublished\":\"2012-04-16T23:35:04+00:00\",\"dateModified\":\"2015-05-27T20:57:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/\"},\"wordCount\":2134,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/decorator.gif\",\"keywords\":[\"C#\"],\"articleSection\":[\"Design Patterns\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/\",\"url\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/\",\"name\":\"Decorator - DaedTech\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/decorator.gif\",\"datePublished\":\"2012-04-16T23:35:04+00:00\",\"dateModified\":\"2015-05-27T20:57:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/daedtech.com\\\/decorator\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#primaryimage\",\"url\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/decorator.gif\",\"contentUrl\":\"http:\\\/\\\/www.dofactory.com\\\/Patterns\\\/Diagrams\\\/decorator.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/decorator\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/daedtech.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Decorator\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#website\",\"url\":\"https:\\\/\\\/daedtech.com\\\/\",\"name\":\"DaedTech\",\"description\":\"Stories about Software\",\"publisher\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/daedtech.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#organization\",\"name\":\"DaedTech LLC\",\"url\":\"https:\\\/\\\/daedtech.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/daedtech.com\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/SmallLogo.jpg\",\"contentUrl\":\"https:\\\/\\\/daedtech.com\\\/wp-content\\\/uploads\\\/2015\\\/07\\\/SmallLogo.jpg\",\"width\":82,\"height\":84,\"caption\":\"DaedTech LLC\"},\"image\":{\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/daedtech.com\\\/#\\\/schema\\\/person\\\/3dae63e91a0fa60c8051a2171fa687d2\",\"name\":\"Erik Dietrich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg\",\"caption\":\"Erik Dietrich\"},\"sameAs\":[\"https:\\\/\\\/daedtech.com\"],\"url\":\"https:\\\/\\\/daedtech.com\\\/author\\\/erik\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Decorator - DaedTech","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/daedtech.com\/decorator\/","twitter_card":"summary_large_image","twitter_title":"Decorator - DaedTech","twitter_description":"Quick Information\/Overview Pattern Type Structural Applicable Language\/Framework Agnostic OOP Pattern Source Gang of Four Difficulty Easy Up Front Definitions Decorator:\u00a0An object that is both an inherits from and operates on another object. Component: Abstract target base class (or interface) of the decorator pattern. Target: For the purposes of this post, I use this term interchangeably...","twitter_image":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif","twitter_misc":{"Written by":"Erik Dietrich","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/daedtech.com\/decorator\/#article","isPartOf":{"@id":"https:\/\/daedtech.com\/decorator\/"},"author":{"name":"Erik Dietrich","@id":"https:\/\/daedtech.com\/#\/schema\/person\/3dae63e91a0fa60c8051a2171fa687d2"},"headline":"Decorator","datePublished":"2012-04-16T23:35:04+00:00","dateModified":"2015-05-27T20:57:00+00:00","mainEntityOfPage":{"@id":"https:\/\/daedtech.com\/decorator\/"},"wordCount":2134,"commentCount":2,"publisher":{"@id":"https:\/\/daedtech.com\/#organization"},"image":{"@id":"https:\/\/daedtech.com\/decorator\/#primaryimage"},"thumbnailUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif","keywords":["C#"],"articleSection":["Design Patterns"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/daedtech.com\/decorator\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/daedtech.com\/decorator\/","url":"https:\/\/daedtech.com\/decorator\/","name":"Decorator - DaedTech","isPartOf":{"@id":"https:\/\/daedtech.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/daedtech.com\/decorator\/#primaryimage"},"image":{"@id":"https:\/\/daedtech.com\/decorator\/#primaryimage"},"thumbnailUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif","datePublished":"2012-04-16T23:35:04+00:00","dateModified":"2015-05-27T20:57:00+00:00","breadcrumb":{"@id":"https:\/\/daedtech.com\/decorator\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/daedtech.com\/decorator\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/daedtech.com\/decorator\/#primaryimage","url":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif","contentUrl":"http:\/\/www.dofactory.com\/Patterns\/Diagrams\/decorator.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/daedtech.com\/decorator\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/daedtech.com\/"},{"@type":"ListItem","position":2,"name":"Decorator"}]},{"@type":"WebSite","@id":"https:\/\/daedtech.com\/#website","url":"https:\/\/daedtech.com\/","name":"DaedTech","description":"Stories about Software","publisher":{"@id":"https:\/\/daedtech.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/daedtech.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/daedtech.com\/#organization","name":"DaedTech LLC","url":"https:\/\/daedtech.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/daedtech.com\/#\/schema\/logo\/image\/","url":"https:\/\/daedtech.com\/wp-content\/uploads\/2015\/07\/SmallLogo.jpg","contentUrl":"https:\/\/daedtech.com\/wp-content\/uploads\/2015\/07\/SmallLogo.jpg","width":82,"height":84,"caption":"DaedTech LLC"},"image":{"@id":"https:\/\/daedtech.com\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/daedtech.com\/#\/schema\/person\/3dae63e91a0fa60c8051a2171fa687d2","name":"Erik Dietrich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/691ca004bd18f464e9467b2f838e8fbc7a9a2c9eb8568b04a834ac653f3ab1d7?s=96&d=wavatar&r=pg","caption":"Erik Dietrich"},"sameAs":["https:\/\/daedtech.com"],"url":"https:\/\/daedtech.com\/author\/erik\/"}]}},"_links":{"self":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts\/978","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/comments?post=978"}],"version-history":[{"count":0,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/posts\/978\/revisions"}],"wp:attachment":[{"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/media?parent=978"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/categories?post=978"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daedtech.com\/wp-json\/wp\/v2\/tags?post=978"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}