In object-oriented programming, the decorator sample is a design sample that enables habits to be added to a person object, dynamically, with out affecting the habits of different objects from the identical class.[1] The decorator sample is usually helpful for adhering to the Single Duty Precept, because it permits performance to be divided between lessons with distinctive areas of concern.[2] The decorator sample is structurally almost equivalent to the chain of duty sample, the distinction being that in a sequence of duty, precisely one of many lessons handles the request, whereas for the decorator, all lessons deal with the request.
Overview[edit]
The decorator[3] design sample is without doubt one of the twenty-three well-known GoF design patterns; these describe tips on how to clear up recurring design issues and design versatile and reusable object-oriented software program—that’s, objects that are simpler to implement, change, check, and reuse.
What issues can it clear up?[edit]
- Tasks needs to be added to (and faraway from) an object dynamically at run-time.[4]
- A versatile different to subclassing for extending performance needs to be supplied.
When utilizing subclassing, completely different subclasses lengthen a category in several methods. However an extension is certain to the category at compile-time and cannot be modified at run-time.
What answer does it describe?[edit]
Outline Decorator
objects that
- implement the interface of the prolonged (embellished) object (
Element
) transparently by forwarding all requests to it - carry out further performance earlier than/after forwarding a request.
This enables working with completely different Decorator
objects to increase the performance of an object dynamically at run-time.
See additionally the UML class and sequence diagram beneath.

The decorator sample can be utilized to increase (enhance) the performance of a sure object statically, or in some circumstances at run-time, independently of different cases of the identical class, supplied some groundwork is finished at design time. That is achieved by designing a brand new Decorator class that wraps the unique class. This wrapping could possibly be achieved by the next sequence of steps:
- Subclass the unique Element class right into a Decorator class (see UML diagram);
- Within the Decorator class, add a Element pointer as a subject;
- Within the Decorator class, move a Element to the Decorator constructor to initialize the Element pointer;
- Within the Decorator class, ahead all Element strategies to the Element pointer; and
- Within the ConcreteDecorator class, override any Element technique(s) whose habits must be modified.
This sample is designed in order that a number of decorators may be stacked on prime of one another, every time including a brand new performance to the overridden technique(s).
Word that decorators and the unique class object share a standard set of options. Within the earlier diagram, the operation() technique was out there in each the embellished and undecorated variations.
The ornament options (e.g., strategies, properties, or different members) are normally outlined by an interface, mixin (a.okay.a. trait) or class inheritance which is shared by the decorators and the embellished object. Within the earlier instance the category Element is inherited by each the ConcreteComponent and the subclasses that descend from Decorator.
The decorator sample is an alternative choice to subclassing. Subclassing provides habits at compile time, and the change impacts all cases of the unique class; adorning can present new habits at run-time for chosen objects.
This distinction turns into most necessary when there are a number of impartial methods of extending performance. In some object-oriented programming languages, lessons can’t be created at runtime, and it’s sometimes not doable to foretell, at design time, what mixtures of extensions shall be wanted. This could imply {that a} new class must be made for each doable mixture. Against this, decorators are objects, created at runtime, and may be mixed on a per-use foundation. The I/O Streams implementations of each Java and the .NET Framework incorporate the decorator sample.
Motivation[edit]

For instance, take into account a window in a windowing system. To permit scrolling of the window’s contents, one could want to add horizontal or vertical scrollbars to it, as acceptable. Assume home windows are represented by cases of the Window interface, and assume this class has no performance for including scrollbars. One might create a subclass ScrollingWindow that gives them, or create a ScrollingWindowDecorator that provides this performance to present Window objects. At this level, both answer could be superb.
Now, assume one additionally needs the power so as to add borders to home windows. Once more, the unique Window class has no help. The ScrollingWindow subclass now poses an issue, as a result of it has successfully created a brand new type of window. If one needs so as to add border help to many however not all home windows, one should create subclasses WindowWithBorder and ScrollingWindowWithBorder and many others. This downside will get worse with each new function or window subtype to be added. For the decorator answer, a brand new BorderedWindowDecorator is created. Any mixture of ScrollingWindowDecorator or BorderedWindowDecorator can enhance present home windows. If the performance must be added to all Home windows, the bottom class may be modified. Alternatively, generally (e.g., utilizing exterior frameworks) it’s not doable, authorized, or handy to switch the bottom class.
Within the earlier instance, the SimpleWindow and WindowDecorator lessons implement the Window interface, which defines the draw() technique and the getDescription() technique which are required on this situation, in an effort to enhance a window management.
A decorator makes it doable so as to add or alter habits of an interface at run-time. Alternatively, the adapter can be utilized when the wrapper should respect a specific interface and should help polymorphic habits, and the Facade when a neater or easier interface to an underlying object is desired.[5]
Sample | Intent |
---|---|
Adapter | Converts one interface to a different in order that it matches what the shopper is anticipating |
Decorator | Dynamically provides duty to the interface by wrapping the unique code |
Facade | Supplies a simplified interface |
Construction[edit]
UML class and sequence diagram[edit]

Within the above UML class diagram,
the summary Decorator
class maintains a reference (element
)
to the embellished object (Element
) and forwards all requests to it
(element.operation()
).
This makes Decorator
clear (invisible) to shoppers of Element
.
Subclasses (Decorator1
,Decorator2
) implement further habits
(addBehavior()
) that needs to be added to the Element
(earlier than/after forwarding a request to it).
The sequence diagram
exhibits the run-time interactions: The Shopper
object
works via Decorator1
and Decorator2
objects to
lengthen the performance of a Component1
object.
The Shopper
calls operation()
on Decorator1
, which forwards the request to Decorator2
.
Decorator2
performs addBehavior()
after forwarding
the request to Component1
and returns to
Decorator1
, which performs addBehavior()
and returns to the Shopper
.
Examples[edit]
Go[edit]
package deal decolog
import (
"log"
"time"
)
//OperateFn represents operations that require ornament
sort OperateFn func()
//Adorn the operation
func Adorn(opFn OperateFn) {
defer func(s time.Time) {
log.Printf("elapsed time %0.second ms", time.Since(s).Nanoseconds()/(1<<20))
}(time.Now())
// actual operation operate
opFn()
}
// package deal primary
package deal primary
import (
"github.com/tkstorm/go-design/structural/decorator/decolog"
"log"
"math/rand"
"time"
)
//output:
//2019/08/19 19:05:24 end motion a
//2019/08/19 19:05:24 elpased time 77 ms
//2019/08/19 19:05:24 end motion b
//2019/08/19 19:05:24 elpased time 88 ms
func primary() {
// enhance log a
decolog.Adorn(decolog.OperateFn(DoActionA))
// enhance log b
decolog.Adorn(decolog.OperateFn(DoActionB))
}
func DoActionA() {
time.Sleep(time.Length(rand.Intn(200)) * time.Millisecond)
log.Println("end motion a")
}
func DoActionB() {
time.Sleep(time.Length(rand.Intn(200)) * time.Millisecond)
log.Println("end motion b")
}
C++[edit]
Two choices are offered right here, first a dynamic, runtime-composable decorator (has points with calling embellished features until proxied explicitly) and a decorator that makes use of mixin inheritance.
Dynamic Decorator[edit]
#embrace <iostream>
#embrace <string>
struct Form {
digital ~Form() = default;
digital std::string GetName() const = 0;
};
struct Circle : Form {
void Resize(float issue) { radius *= issue; }
std::string GetName() const override {
return std::string("A circle of radius ") + std::to_string(radius);
}
float radius = 10.0f;
};
struct ColoredShape : Form {
ColoredShape(const std::string& coloration, Form* form)
: coloration(coloration), form(form) {}
std::string GetName() const override {
return form->GetName() + " which is coloured " + coloration;
}
std::string coloration;
Form* form;
};
int primary() {
Circle circle;
ColoredShape colored_shape("pink", &circle);
std::cout << colored_shape.GetName() << std::endl;
}
#embrace <reminiscence>
#embrace <iostream>
#embrace <string>
struct WebPage
{
digital void show()=0;
digital ~WebPage() = default;
};
struct BasicWebPage : WebPage
{
std::string html;
void show() override
{
std::cout << "Fundamental WEB web page" << std::endl;
}
~BasicWebPage()=default;
};
struct WebPageDecorator : WebPage
{
WebPageDecorator(std::unique_ptr<WebPage> webPage): _webPage(std::transfer(webPage))
{
}
void show() override
{
_webPage->show();
}
~WebPageDecorator()=default;
personal:
std::unique_ptr<WebPage> _webPage;
};
struct AuthenticatedWebPage : WebPageDecorator
{
AuthenticatedWebPage(std::unique_ptr<WebPage> webPage):
WebPageDecorator(std::transfer(webPage))
{}
void authenticateUser()
{
std::cout << "authentification performed" << std::endl;
}
void show() override
{
authenticateUser();
WebPageDecorator::show();
}
~AuthenticatedWebPage()=default;
};
struct AuthorizedWebPage : WebPageDecorator
{
AuthorizedWebPage(std::unique_ptr<WebPage> webPage):
WebPageDecorator(std::transfer(webPage))
{}
void authorizedUser()
{
std::cout << "approved performed" << std::endl;
}
void show() override
{
authorizedUser();
WebPageDecorator::show();
}
~AuthorizedWebPage()=default;
};
int primary(int argc, char* argv[])
{
std::unique_ptr<WebPage> myPage = std::make_unique<BasicWebPage>();
myPage = std::make_unique<AuthorizedWebPage>(std::transfer(myPage));
myPage = std::make_unique<AuthenticatedWebPage>(std::transfer(myPage));
myPage->show();
std::cout << std::endl;
return 0;
}
Static Decorator (Mixin Inheritance)[edit]
This instance demonstrates a static Decorator implementation, which is feasible on account of C++ potential to inherit from the template argument.
#embrace <iostream>
#embrace <string>
struct Circle {
void Resize(float issue) { radius *= issue; }
std::string GetName() const {
return std::string("A circle of radius ") + std::to_string(radius);
}
float radius = 10.0f;
};
template <typename T>
struct ColoredShape : public T {
ColoredShape(const std::string& coloration) : coloration(coloration) {}
std::string GetName() const {
return T::GetName() + " which is coloured " + coloration;
}
std::string coloration;
};
int primary() {
ColoredShape<Circle> red_circle("pink");
std::cout << red_circle.GetName() << std::endl;
red_circle.Resize(1.5f);
std::cout << red_circle.GetName() << std::endl;
}
Java[edit]
First instance (window/scrolling situation)[edit]
The next Java instance illustrates using decorators utilizing the window/scrolling situation.
// The Window interface class
public interface Window {
void draw(); // Attracts the Window
String getDescription(); // Returns an outline of the Window
}
// Implementation of a easy Window with none scrollbars
class SimpleWindow implements Window {
@Override
public void draw() {
// Draw window
}
@Override
public String getDescription() {
return "easy window";
}
}
The next lessons comprise the decorators for all Window lessons, together with the decorator lessons themselves.
// summary decorator class - word that it implements Window
summary class WindowDecorator implements Window {
personal remaining Window windowToBeDecorated; // the Window being embellished
public WindowDecorator (Window windowToBeDecorated) {
this.windowToBeDecorated = windowToBeDecorated;
}
@Override
public void draw() {
windowToBeDecorated.draw(); //Delegation
}
@Override
public String getDescription() {
return windowToBeDecorated.getDescription(); //Delegation
}
}
// The primary concrete decorator which provides vertical scrollbar performance
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator (Window windowToBeDecorated) {
tremendous(windowToBeDecorated);
}
@Override
public void draw() {
tremendous.draw();
drawVerticalScrollBar();
}
personal void drawVerticalScrollBar() {
// Draw the vertical scrollbar
}
@Override
public String getDescription() {
return tremendous.getDescription() + ", together with vertical scrollbars";
}
}
// The second concrete decorator which provides horizontal scrollbar performance
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window windowToBeDecorated) {
tremendous(windowToBeDecorated);
}
@Override
public void draw() {
tremendous.draw();
drawHorizontalScrollBar();
}
personal void drawHorizontalScrollBar() {
// Draw the horizontal scrollbar
}
@Override
public String getDescription() {
return tremendous.getDescription() + ", together with horizontal scrollbars";
}
}
This is a check program that creates a Window occasion which is absolutely embellished (i.e., with vertical and horizontal scrollbars), and prints its description:
public class DecoratedWindowTest {
public static void primary(String[] args) {
// Create a embellished Window with horizontal and vertical scrollbars
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator (new SimpleWindow()));
// Print the Window's description
System.out.println(decoratedWindow.getDescription());
}
}
Under is the JUnit check class for the Take a look at Pushed Improvement
import static org.junit.Assert.assertEquals;
import org.junit.Take a look at;
public class WindowDecoratorTest {
@Take a look at
public void testWindowDecoratorTest() {
Window decoratedWindow = new HorizontalScrollBarDecorator(new VerticalScrollBarDecorator(new SimpleWindow()));
// assert that the outline certainly contains horizontal + vertical scrollbars
assertEquals("easy window, together with vertical scrollbars, together with horizontal scrollbars", decoratedWindow.getDescription())
}
}
The output of this program is “easy window, together with vertical scrollbars, together with horizontal scrollbars”. Discover how the getDescription technique of the 2 decorators first retrieve the embellished Window‘s description and decorates it with a suffix.
Second instance (espresso making situation)[edit]
The following Java instance illustrates using decorators utilizing espresso making situation.
On this instance, the situation solely contains value and elements.
// The interface Espresso defines the performance of Espresso carried out by decorator
public interface Espresso {
public double getCost(); // Returns the price of the espresso
public String getIngredients(); // Returns the elements of the espresso
}
// Extension of a easy espresso with none additional elements
public class SimpleCoffee implements Espresso {
@Override
public double getCost() {
return 1;
}
@Override
public String getIngredients() {
return "Espresso";
}
}
The next lessons comprise the decorators for all Espresso lessons, together with the decorator lessons themselves.
// Summary decorator class - word that it implements Espresso interface
public summary class CoffeeDecorator implements Espresso {
personal remaining Espresso decoratedCoffee;
public CoffeeDecorator(Espresso c) {
this.decoratedCoffee = c;
}
@Override
public double getCost() { // Implementing strategies of the interface
return decoratedCoffee.getCost();
}
@Override
public String getIngredients() {
return decoratedCoffee.getIngredients();
}
}
// Decorator WithMilk mixes milk into espresso.
// Word it extends CoffeeDecorator.
class WithMilk extends CoffeeDecorator {
public WithMilk(Espresso c) {
tremendous(c);
}
@Override
public double getCost() { // Overriding strategies outlined within the summary superclass
return tremendous.getCost() + 0.5;
}
@Override
public String getIngredients() {
return tremendous.getIngredients() + ", Milk";
}
}
// Decorator WithSprinkles mixes sprinkles onto espresso.
// Word it extends CoffeeDecorator.
class WithSprinkles extends CoffeeDecorator {
public WithSprinkles(Espresso c) {
tremendous(c);
}
@Override
public double getCost() {
return tremendous.getCost() + 0.2;
}
@Override
public String getIngredients() {
return tremendous.getIngredients() + ", Sprinkles";
}
}
This is a check program that creates a Espresso occasion which is absolutely embellished (with milk and sprinkles), and calculate value of espresso and prints its elements:
public class Principal {
public static void printInfo(Espresso c) {
System.out.println("Value: " + c.getCost() + "; Elements: " + c.getIngredients());
}
public static void primary(String[] args) {
Espresso c = new SimpleCoffee();
printInfo(c);
c = new WithMilk(c);
printInfo(c);
c = new WithSprinkles(c);
printInfo(c);
}
}
The output of this program is given beneath:
Value: 1.0; Elements: Espresso Value: 1.5; Elements: Espresso, Milk Value: 1.7; Elements: Espresso, Milk, Sprinkles
PHP[edit]
summary class Element
{
protected $information;
protected $worth;
summary public operate getData();
summary public operate getValue();
}
class ConcreteComponent extends Element
{
public operate __construct()
{
$this->worth = 1000;
$this->information = "Concrete Element:t{$this->worth}n";
}
public operate getData()
{
return $this->information;
}
public operate getValue()
{
return $this->worth;
}
}
summary class Decorator extends Element
{
}
class ConcreteDecorator1 extends Decorator
{
public operate __construct(Element $information)
{
$this->worth = 500;
$this->information = $information;
}
public operate getData()
{
return $this->information->getData() . "Concrete Decorator 1:t{$this->worth}n";
}
public operate getValue()
{
return $this->worth + $this->information->getValue();
}
}
class ConcreteDecorator2 extends Decorator
{
public operate __construct(Element $information)
{
$this->worth = 500;
$this->information = $information;
}
public operate getData()
{
return $this->information->getData() . "Concrete Decorator 2:t{$this->worth}n";
}
public operate getValue()
{
return $this->worth + $this->information->getValue();
}
}
class Shopper
{
personal $element;
public operate __construct()
{
$this->element = new ConcreteComponent();
$this->element = $this->wrapComponent($this->element);
echo $this->element->getData();
echo "Shopper:ttt";
echo $this->element->getValue();
}
personal operate wrapComponent(Element $element)
{
$component1 = new ConcreteDecorator1($element);
$component2 = new ConcreteDecorator2($component1);
return $component2;
}
}
$shopper = new Shopper();
// End result: #quanton81
//Concrete Element: 1000
//Concrete Decorator 1: 500
//Concrete Decorator 2: 500
//Shopper: 2000
Python[edit]
The next Python instance, taken from Python Wiki – DecoratorPattern, exhibits us tips on how to pipeline decorators to dynamically add many behaviors in an object:
"""
Demonstrated decorators in a world of a 10x10 grid of values 0-255.
"""
import random
def s32_to_u16(x):
if x < 0:
signal = 0xf000
else:
signal = 0
backside = x & 0x00007fff
return backside | signal
def seed_from_xy(x, y):
return s32_to_u16(x) | (s32_to_u16(y) << 16)
class RandomSquare:
def __init__(s, seed_modifier):
s.seed_modifier = seed_modifier
def get(s, x, y):
seed = seed_from_xy(x, y) ^ s.seed_modifier
random.seed(seed)
return random.randint(0, 255)
class DataSquare:
def __init__(s, initial_value=None):
s.information = [initial_value] * 10 * 10
def get(s, x, y):
return s.information[(y * 10) + x] # sure: these are all 10x10
def set(s, x, y, u):
s.information[(y * 10) + x] = u
class CacheDecorator:
def __init__(s, embellished):
s.embellished = embellished
s.cache = DataSquare()
def get(s, x, y):
if s.cache.get(x, y) == None:
s.cache.set(x, y, s.embellished.get(x, y))
return s.cache.get(x, y)
class MaxDecorator:
def __init__(s, embellished, max):
s.embellished = embellished
s.max = max
def get(s, x, y):
if s.embellished.get(x, y) > s.max:
return s.max
return s.embellished.get(x, y)
class MinDecorator:
def __init__(s, embellished, min):
s.embellished = embellished
s.min = min
def get(s, x, y):
if s.embellished.get(x, y) < s.min:
return s.min
return s.embellished.get(x, y)
class VisibilityDecorator:
def __init__(s, embellished):
s.embellished = embellished
def get(s, x, y):
return s.embellished.get(x, y)
def draw(s):
for y in vary(10):
for x in vary(10):
print "%3d" % s.get(x, y),
print
# Now, construct up a pipeline of decorators:
random_square = RandomSquare(635)
random_cache = CacheDecorator(random_square)
max_filtered = MaxDecorator(random_cache, 200)
min_filtered = MinDecorator(max_filtered, 100)
remaining = VisibilityDecorator(min_filtered)
remaining.draw()
Word:
Please don’t confuse the Decorator Sample (or an implementation of this design sample in Python – because the above instance) with Python Decorators, a Python language function. They’re various things.
Second to the Python Wiki:
The Decorator Sample is a sample described within the Design Patterns Ebook. It’s a means of apparently modifying an object’s habits, by enclosing it inside a adorning object with an identical interface.
This isn’t to be confused with Python Decorators, which is a language function for dynamically modifying a operate or class.[7]
Crystal[edit]
summary class Espresso
summary def value
summary def elements
finish
# Extension of a easy espresso
class SimpleCoffee < Espresso
def value
1.0
finish
def elements
"Espresso"
finish
finish
# Summary decorator
class CoffeeDecorator < Espresso
protected getter decorated_coffee : Espresso
def initialize(@decorated_coffee)
finish
def value
decorated_coffee.value
finish
def elements
decorated_coffee.elements
finish
finish
class WithMilk < CoffeeDecorator
def value
tremendous + 0.5
finish
def elements
tremendous + ", Milk"
finish
finish
class WithSprinkles < CoffeeDecorator
def value
tremendous + 0.2
finish
def elements
tremendous + ", Sprinkles"
finish
finish
class Program
def print(espresso : Espresso)
places "Value: #{espresso.value}; Elements: #{espresso.elements}"
finish
def initialize
espresso = SimpleCoffee.new
print(espresso)
espresso = WithMilk.new(espresso)
print(espresso)
espresso = WithSprinkles.new(espresso)
print(espresso)
finish
finish
Program.new
Output:
Value: 1.0; Elements: Espresso Value: 1.5; Elements: Espresso, Milk Value: 1.7; Elements: Espresso, Milk, Sprinkles
C#[edit]
namespace WikiDesignPatterns
{
public interface IBike
{
string GetDetails();
double GetPrice();
}
public class AluminiumBike : IBike
{
public double GetPrice()
{
return 100;
}
public string GetDetails()
{
return "Aluminium Bike";
}
}
public class CarbonBike : IBike
{
public double GetPrice()
{
return 1000;
}
public string GetDetails()
{
return "Carbon";
}
}
public summary class BikeAccessories : IBike
{
personal readonly IBike _bike;
public BikeAccessories(IBike bike)
{
_bike = bike;
}
public digital double GetPrice()
{
return _bike.GetPrice();
}
public digital string GetDetails()
{
return _bike.GetDetails();
}
}
public class SecurityPackage : BikeAccessories
{
public SecurityPackage(IBike bike):base(bike)
{
}
public override string GetDetails()
{
return base.GetDetails() + " + Safety Bundle";
}
public override double GetPrice()
{
return base.GetPrice() + 1;
}
}
public class SportPackage : BikeAccessories
{
public SportPackage(IBike bike) : base(bike)
{
}
public override string GetDetails()
{
return base.GetDetails() + " + Sport Bundle";
}
public override double GetPrice()
{
return base.GetPrice() + 10;
}
}
public class BikeShop
{
public static void UpgradeBike()
{
var basicBike = new AluminiumBike();
BikeAccessories upgraded = new SportPackage(basicBike);
upgraded = new SecurityPackage(upgraded);
Console.WriteLine($"Bike: '{upgraded.GetDetails()}' Value: {upgraded.GetPrice()}");
}
}
}
Output:
Bike: 'Aluminium Bike + Sport Bundle + Safety Bundle' Value: 111
See additionally[edit]
References[edit]
- ^ Gamma, Erich; et al. (1995). Design Patterns. Studying, MA: Addison-Wesley Publishing Co, Inc. pp. 175ff. ISBN 0-201-63361-2.
- ^ “How one can Implement a Decorator Sample”. Archived from the unique on 2015-07-07.
- ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Components of Reusable Object-Oriented Software program. Addison Wesley. pp. 175ff. ISBN 0-201-63361-2.CS1 maint: a number of names: authors listing (hyperlink)
- ^ “The Decorator design sample – Drawback, Answer, and Applicability”. w3sDesign.com. Retrieved 2017-08-12.
- ^ Freeman, Eric; Freeman, Elisabeth; Sierra, Kathy; Bates, Bert (2004). Hendrickson, Mike; Loukides, Mike (eds.). Head First Design Patterns (paperback). 1. O’Reilly. pp. 243, 252, 258, 260. ISBN 978-0-596-00712-6. Retrieved 2012-07-02.
- ^ “The Decorator design sample – Construction and Collaboration”. w3sDesign.com. Retrieved 2017-08-12.
- ^ “DecoratorPattern – Python Wiki”. wiki.python.org.
Exterior hyperlinks[edit]