Click here to Skip to main content
13,505,855 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


12 bookmarked
Posted 9 Feb 2014

Avoid Creating Inflexible Classes. Use Decorators.

, 9 Feb 2014
Rate this:
Please Sign up or sign in to vote.
Consider the Decorator Pattern!


Far too often, we (fellow programmers) make the decision to use standard inheritance when adding new functionality to classes. However, there are many occasions in which this leads to inflexible code. We then scratch our heads and wonder how it happened.

Let me explain with an example. Suppose we have an application that calculates the price of cookies. We create hierarchies like Cookie, ChocolateChipCookie, PeanutButterCookie, etc. Let's say we have a GetPrice() overloaded method for each class. Everything works great until the cookie factory manager tells us that now they are manufacturing peanut butter chocolate chip cookies. If we then start creating classes (such as a ChocolateChipPeanutButterCookie), the code becomes unruly rather quickly (in particular trying to separate class responsibilities). So, this design was not flexible enough to handle this simple request.

However, using the decorator pattern is perfect for this scenario. The decorator pattern allows us to add behavior to objects at run-time without directly relying on inheritance. A decorator conforms to the component it is decorating. An example below will make this clear.

Using the Code

In this example, let us create some cost requirements to make it more concrete. Let us assume the base cost of a cookie with its core ingredients is 30 cents, the cost to add chocolate chips is 20 cents, and 40 cents to include peanut butter (my favorite).

Please look at the code below.

Both the ChocolateChipCookie and PeanutButterCookie classes allow for an instance of an ICookie to be passed in the constructor. ChocolateChipCookie decorates the Cookie and adds the price of the chocolate chips to the total. The PeanutButter cookie does the same.

So, to create a cookie that has both chocolate chips and peanut butter, just create a new PeanutButterCookie(chocolateChipCookie);

This allows for your classes to contain any combinations without a rigid hierarchy.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
    class Program
        private interface ICookie
            float GetPrice();
        private class Cookie : ICookie
            public float GetPrice()
                return (float) 0.30;
        //Decorator 1
        private class ChocolateChipCookie : ICookie
            private ICookie _cookie;
            private float _priceofChocolateChip = (float) 0.20;
            public ChocolateChipCookie(ICookie cookie)
                _cookie = cookie;
            public float GetPrice()
                return _cookie.GetPrice() + _priceofChocolateChip;
        //Decorator 2
        private class PeanutButterCookie : ICookie
            private ICookie _cookie;
            private float _priceofPeanutButter = (float) 0.40;
            public PeanutButterCookie(ICookie cookie)
                _cookie = cookie;
            public float GetPrice()
                //get price and add to it
                return _cookie.GetPrice() + _priceofPeanutButter;
        static void Main(string[] args)
            var chocolateChipCookie = new ChocolateChipCookie(new Cookie());
            var peanutButterCookie = new PeanutButterCookie(new Cookie());
            // easy to create combinations! 

            var peanutButterchocolateChipCookie = new PeanutButterCookie(chocolateChipCookie);
            Console.WriteLine("price of chocolate chip cookie: " 
            	+ chocolateChipCookie.GetPrice());
            Console.WriteLine("price of peanutbutter cookie: " 
            	+ peanutButterCookie.GetPrice());
            Console.WriteLine("price of peanutbutter chocolate chip cookie: " 
            	+ peanutButterchocolateChipCookie.GetPrice());

When executed, you should see the following output:

Price of chocolate chip cookie: 0.5 
Price of peanutbutter cookie: 0.7
Price of peanutbutter chocolate chip cookie: 0.9

A helpful way to identify when to use the decorator pattern is to determine if the new behavior is an option or not. If they are "options" where different combinations are allowed, then the decorator pattern is the way to go.

I am very hungry for some reason, so I am going to get going... Happy coding.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Bruce S Oberhand
United States United States
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionThanks Pin
AnotherKen10-Feb-14 18:54
memberAnotherKen10-Feb-14 18:54 
QuestionThanks A Lot Pin
Matt U.10-Feb-14 5:05
memberMatt U.10-Feb-14 5:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.180417.1 | Last Updated 9 Feb 2014
Article Copyright 2014 by Bruce S Oberhand
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid