{"id":6464,"date":"2022-10-23T17:24:28","date_gmt":"2022-10-23T17:24:28","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-decorator-pattern\/"},"modified":"2022-10-23T17:24:28","modified_gmt":"2022-10-23T17:24:28","slug":"the-decorator-pattern","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-decorator-pattern\/","title":{"rendered":"The Decorator Pattern"},"content":{"rendered":"<p><span data-offset-key=\"5aatf-0-0\"><span data-text=\"true\">The Decorator Pattern&#8217;s job is to extend an object with responsibilities dynamically. Let me, in today&#8217;s post, dig deeper.<\/span><\/span><\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6385\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/06\/patterns.png\" alt=\"patterns\" width=\"650\" height=\"330\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>First, the Decorator Pattern is the third structural pattern from the book &#8220;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Design_Patterns\">Design Patterns: Elements of Reusable Object-Oriented Software&#8221;<\/a>, I present in my series about patterns. The first two ones were the Adapter Pattern and the Bridge Pattern.<\/p>\n<p>Second, don&#8217;t confuse the Decorator Pattern with the <a href=\"https:\/\/realpython.com\/primer-on-python-decorators\/\">Decorator Idiom<\/a> in Python. Their intention is different. The Decorator Pattern allows you to extend objects dynamically, but the Decorator Idiom in Python enables you to extend functions dynamically.<\/p>\n<p>Here are the facts about the Decorator Pattern.<\/p>\n<h2>Decorator Pattern<\/h2>\n<h3>Purpose<\/h3>\n<ul>\n<li>Dynamically extends an object with responsibilities<\/li>\n<\/ul>\n<h3>Also known as<\/h3>\n<ul>\n<li>Wrapper<\/li>\n<\/ul>\n<h3>Use Case<\/h3>\n<ul>\n<li>Add or remove new responsibilities from individual objects at run time<\/li>\n<li>The enhancement of the class hierarchy using subclassing (see Adapter Pattern) is not applicable<\/li>\n<\/ul>\n<h3>Structure<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6461\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/Decorator.png\" alt=\"Decorator\" width=\"315\" height=\"368\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/Decorator.png 315w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/Decorator-257x300.png 257w\" sizes=\"auto, (max-width: 315px) 100vw, 315px\" \/><\/p>\n<p><strong><code>Component<\/code><\/strong><\/p>\n<ul>\n<li>Defines the common interface for the <code>Decorator<\/code> and the <code>ConcreteComponent<\/code><\/li>\n<\/ul>\n<p><strong><code>ConcreteComponent<\/code><\/strong><\/p>\n<ul>\n<li>The object to be decorated<\/li>\n<li>It defines the basic behavior<\/li>\n<\/ul>\n<p><strong><code>Decorator<\/code><\/strong><\/p>\n<ul>\n<li>Implements the interface of <code>Component<\/code><\/li>\n<li>It has a reference to the <code>Component<\/code><\/li>\n<li>\n<div>It delegates all operations to the <code>Component; <\/code>the Component could either be an additional <code>ConcreteDecorator<\/code> or a <code>ConcreteComponent<br \/><\/code><\/div>\n<\/li>\n<\/ul>\n<p><code><strong>ConcreteDecorator<\/strong><\/code><\/p>\n<ul>\n<li>Extends the behavior of the <code>Component <\/code><\/li>\n<li>Overrides the member functions of its base <code>Component<br \/><\/code><\/li>\n<li>Calls typically in its overriding member function the overridden member function of it base <code>Component<\/code><\/li>\n<\/ul>\n<p>An important observation of the Decorator Pattern is that multiple decorators can be plugged on top of each other, with each decorator adding new functionality to the overridden member functions.<\/p>\n<\/p>\n<h3>Example<\/h3>\n<p>The following example is based on the example in the Wikipedia page <a href=\"https:\/\/en.wikipedia.org\/wiki\/Decorator_pattern\">Decorator Pattern<\/a>.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ decorator.cpp (based on https:\/\/en.wikipedia.org\/wiki\/Decorator_pattern)<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Shape {\r\n  <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #555555;\">~<\/span>Shape() <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">default<\/span>;\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> std<span style=\"color: #555555;\">::<\/span>string GetName() <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Circle <span style=\"color: #555555;\">:<\/span> Shape {\r\n  <span style=\"color: #007788; font-weight: bold;\">void<\/span> Resize(<span style=\"color: #007788; font-weight: bold;\">float<\/span> factor) { radius <span style=\"color: #555555;\">*=<\/span> factor; }\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>string GetName() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>string(<span style=\"color: #cc3300;\">\"A circle of radius \"<\/span>) <span style=\"color: #555555;\">+<\/span> std<span style=\"color: #555555;\">::<\/span>to_string(radius);\r\n  }\r\n\r\n  <span style=\"color: #007788; font-weight: bold;\">float<\/span> radius <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">10.0f<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> ColoredShape <span style=\"color: #555555;\">:<\/span> Shape {\r\n  ColoredShape(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> color, Shape<span style=\"color: #555555;\">*<\/span> shape)             <em><span style=\"color: #0099ff;\"> \/\/ (1)<\/span><\/em>\r\n      <span style=\"color: #555555;\">:<\/span> color(color), shape(shape) {}\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>string GetName() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override {\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> shape<span style=\"color: #555555;\">-&gt;<\/span>GetName() <span style=\"color: #555555;\">+<\/span> <span style=\"color: #cc3300;\">\" which is colored \"<\/span> <span style=\"color: #555555;\">+<\/span> color <span style=\"color: #555555;\">+<\/span> <span style=\"color: #cc3300;\">\".\"<\/span>;   <em><span style=\"color: #0099ff;\">\/\/ (2)<\/span><\/em>\r\n  }\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>string color;\r\n  Shape<span style=\"color: #555555;\">*<\/span> shape;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n  Circle circle;\r\n  ColoredShape colored_shape(<span style=\"color: #cc3300;\">\"red\"<\/span>, <span style=\"color: #555555;\">&amp;<\/span>circle);\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> colored_shape.GetName() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In this example, <code>Shape <\/code>is the <code>Component<\/code>.&nbsp; Circle stands for the <code>ConcreteComponent<\/code>, and <code>ColoredShape<\/code> for the Decorator. <code>ColoredShape<\/code> gets it <code>Shape<\/code> in its constructor (line 1), invokes it <code>shape-&gt;GetName()<\/code> member function in line 2, and decorates it with its <code>color<\/code>.<\/p>\n<p>Here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6462\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorWiki.png\" alt=\"decoratorWiki\" width=\"400\" height=\"147\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorWiki.png 606w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorWiki-300x110.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Deriving a <code>FramedShape<\/code> as an additional <code>Decorator<\/code>, allows it to plug them together in arbitrary ways:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0px; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ decoratorFrame.cpp (based on https:\/\/en.wikipedia.org\/wiki\/Decorator_pattern)<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Shape{\r\n  <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> std<span style=\"color: #555555;\">::<\/span>string str() <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Circle<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Shape{\r\n  <span style=\"color: #007788; font-weight: bold;\">float<\/span> radius <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">10.0f<\/span>;\r\n  \r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>string str() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override{\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> std<span style=\"color: #555555;\">::<\/span>string(<span style=\"color: #cc3300;\">\"A circle of radius \"<\/span>) <span style=\"color: #555555;\">+<\/span> std<span style=\"color: #555555;\">::<\/span>to_string(radius);\r\n  }\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">ColoredShape<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Shape{\r\n  std<span style=\"color: #555555;\">::<\/span>string color;\r\n  Shape<span style=\"color: #555555;\">&amp;<\/span> shape;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  ColoredShape(std<span style=\"color: #555555;\">::<\/span>string c, Shape<span style=\"color: #555555;\">&amp;<\/span> s)<span style=\"color: #555555;\">:<\/span> color{c}, shape{s} {}\r\n  std<span style=\"color: #555555;\">::<\/span>string str() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override{\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> shape.str() <span style=\"color: #555555;\">+<\/span> std<span style=\"color: #555555;\">::<\/span>string(<span style=\"color: #cc3300;\">\" which is coloured \"<\/span>) <span style=\"color: #555555;\">+<\/span> color;\r\n  }\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">FramedShape<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Shape{\r\n  Shape<span style=\"color: #555555;\">&amp;<\/span> shape;\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n  FramedShape(Shape<span style=\"color: #555555;\">&amp;<\/span> s)<span style=\"color: #555555;\">:<\/span> shape{s} {}\r\n  std<span style=\"color: #555555;\">::<\/span>string str() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override{\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> shape.str() <span style=\"color: #555555;\">+<\/span> std<span style=\"color: #555555;\">::<\/span>string(<span style=\"color: #cc3300;\">\" and has a frame\"<\/span>);\r\n  }\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  Circle circle;\r\n  ColoredShape coloredShape(<span style=\"color: #cc3300;\">\"red\"<\/span>, circle);    <span style=\"color: #0099ff;\"><em>\/\/ (1)<\/em><\/span>\r\n  FramedShape framedShape1(circle);           <span style=\"color: #0099ff;\"> <em>\/\/ (2)<\/em><\/span>\r\n  FramedShape framedShape2(coloredShape);     <span style=\"color: #0099ff;\"><em> \/\/ (3)<\/em><\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> circle.str() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> coloredShape.str() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> framedShape1.str() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> framedShape2.str() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The <code>ColoredShape<\/code> takes a <code>Circle<\/code> (line 1), the <code>FramedShape <\/code>a Circle (line 2), or a C<code>oloredShape<\/code> (line 3).&nbsp; The corresponding member functions <code>str<\/code> display the various combinations.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6463\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorFrame.png\" alt=\"decoratorFrame\" width=\"600\" height=\"193\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorFrame.png 756w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/decoratorFrame-300x97.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h3>Related Patterns<\/h3>\n<ul>\n<li>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Composite_pattern\">Composite Pattern<\/a> is a structural pattern similar to the Decorator. The main difference is that the Decorator Pattern has only one child. Additionally, the Decorator Pattern adds new responsibility to an object, while the Composite Pattern sums up the results of its children.<\/li>\n<li>The<a href=\"https:\/\/en.wikipedia.org\/wiki\/Adapter_pattern\"> Adapter Pattern<\/a> changes the interface of an object, but a Decorator extends the responsibilities of the object.<\/li>\n<li>The<a href=\"https:\/\/en.wikipedia.org\/wiki\/Bridge_pattern\"> Bridge Pattern<\/a>&#8216;s purpose is to separate the interface from the implementation. Decorators are pluggable, but neither bridges nor adapters.<\/li>\n<li>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Strategy_pattern\">Strategy Pattern<\/a> uses objects to change the implementation, but the Decorator uses objects to extend the responsibilities of the object.<\/li>\n<\/ul>\n<p>Let&#8217;s talk about the pros and cons of the Decorator Pattern.<\/p>\n<h3>Pros and Cons<\/h3>\n<h4>Pros<\/h4>\n<ul>\n<li>The decorators can be arbitrarily plugged on run time on top of each other.<\/li>\n<li>Each decorator can implement a behavior variant and follow the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Single-responsibility_principle\">single responsibility principle<\/a>.<\/li>\n<\/ul>\n<h4>Cons<\/h4>\n<ul>\n<li>Due to these delegated member function calls, the control flow is difficult to follow.<\/li>\n<li>The delegated member function call may affect the performance of the program.<\/li>\n<li>It is pretty complicated to remove a decorator out of a stack of decorators.<\/li>\n<\/ul>\n<h2>What&#8217;s Next?<\/h2>\n<p>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Composite_pattern\">Composite Pattern<\/a> is a structural pattern and pretty similar to the Decorator Pattern. The main difference is that the Decorator Pattern has only one child. Additionally, the Decorator Pattern adds new responsibility to an object, while the Composite Pattern sums up the results of its children.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Decorator Pattern&#8217;s job is to extend an object with responsibilities dynamically. Let me, in today&#8217;s post, dig deeper.<\/p>\n","protected":false},"author":21,"featured_media":6385,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[379],"tags":[],"class_list":["post-6464","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-patterns"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6464","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=6464"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6464\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/6385"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=6464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}