{"id":6470,"date":"2022-10-30T23:32:21","date_gmt":"2022-10-30T23:32:21","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/the-composite-pattern\/"},"modified":"2022-10-30T23:32:21","modified_gmt":"2022-10-30T23:32:21","slug":"the-composite-pattern","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/the-composite-pattern\/","title":{"rendered":"The Composite Pattern"},"content":{"rendered":"<p>The Composite Pattern allows you to compose objects into tree structures and treat the individual object and composite objects uniformly.<\/p>\n<p><!--more--><\/p>\n<p><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;\" moz-do-not-send=\"false\" \/><\/p>\n<p>The Composite Pattern is similar to the Decorator Pattern I presented in my last post.&nbsp; Both patterns are of structural nature. The main difference is that the Composite Pattern composites tree structures, but the Decorator Pattern only has one object.<\/p>\n<p>Here are more details about the Composite Pattern.<\/p>\n<h2>Composite Pattern<\/h2>\n<h3>Purpose<\/h3>\n<ul>\n<li>Combines objects into tree structures to handle them uniformly<\/li>\n<\/ul>\n<h3>Use Case<\/h3>\n<ul>\n<li>Represents part\/whole hierarchies<\/li>\n<li>Clients can treat single and composite objects equally<\/li>\n<\/ul>\n<h3>Structure<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6468\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/CompositePattern.png\" alt=\"CompositePattern\" width=\"500\" height=\"263\" style=\"display: block; margin-left: auto; margin-right: auto;\" moz-do-not-send=\"false\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/CompositePattern.png 380w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/CompositePattern-300x158.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p><code>Component<\/code><\/p>\n<ul>\n<li>Defines the interface<\/li>\n<li>Defines an interface so that the <code><span style=\"font-family: Courier New, Courier, monospace;\">Composite<\/span> <\/code>(parent) can access its <code>Component<\/code>&#8216;s child&nbsp; (optionally)<\/li>\n<\/ul>\n<p><code>Leaf<\/code><\/p>\n<ul>\n<li>Represents the singular object<\/li>\n<li>Implements the interface<\/li>\n<\/ul>\n<p><code>Composite<\/code><\/p>\n<ul>\n<li>Represents the composite object<\/li>\n<li>Defines member functions to manipulate its children<\/li>\n<\/ul>\n<p>When you perform an operation on the tree structure, the operation can be performed on a leaf node or a composite node. The operation is directly performed if it is a leaf node. The operation is delegated to all children components if it is a composite node. A composite node has a list of children and member functions to add or remove those. Consequentially, each component (leaf node or composite node) can handle the operation appropriately.<\/p>\n<\/p>\n<h3>Example<\/h3>\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: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ composite.cpp<\/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<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Graphic<\/span> {\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #007788; font-weight: bold;\">void<\/span> print() <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">virtual<\/span> <span style=\"color: #555555;\">~<\/span>Graphic() {} \r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">GraphicComposite<\/span> <span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Graphic {\r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">const<\/span> Graphic<span style=\"color: #555555;\">*&gt;<\/span> children;                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> name;\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> <span style=\"color: #cc00ff;\">GraphicComposite<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> n)<span style=\"color: #555555;\">:<\/span> name(n){}\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> print() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override {                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> c<span style=\"color: #555555;\">:<\/span> children) c<span style=\"color: #555555;\">-&gt;<\/span>print();\r\n    }\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> add(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Graphic<span style=\"color: #555555;\">*<\/span> component) {                           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        children.push_back(component);\r\n    }\r\n\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> remove(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Graphic<span style=\"color: #555555;\">*<\/span> component) {                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>erase(children, component);\r\n    }\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Ellipse<\/span><span style=\"color: #555555;\">:<\/span> <span style=\"color: #006699; font-weight: bold;\">public<\/span> Graphic {\r\n <span style=\"color: #9999ff;\">private:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> name;\r\n <span style=\"color: #9999ff;\">public:<\/span>\r\n    <span style=\"color: #006699; font-weight: bold;\">explicit<\/span> <span style=\"color: #cc00ff;\">Ellipse<\/span>(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> n)<span style=\"color: #555555;\">:<\/span> name (n) {}\r\n    <span style=\"color: #007788; font-weight: bold;\">void<\/span> print() <span style=\"color: #006699; font-weight: bold;\">const<\/span> override {                                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n        std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> name <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/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    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">'\\n'<\/span>;\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string el1 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"ellipse1\"<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string el2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"ellipse2\"<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string el3 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"ellipse3\"<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string el4 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"ellipse4\"<\/span>;\r\n\r\n    Ellipse ellipse1(el1);\r\n    Ellipse ellipse2(el2);\r\n    Ellipse ellipse3(el3);\r\n    Ellipse ellipse4(el4);\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string graph1 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"graphic1\"<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string graph2 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"graphic2\"<\/span>;\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string graph3 <span style=\"color: #555555;\">=<\/span> <span style=\"color: #cc3300;\">\"graphic3\"<\/span>;\r\n\r\n    GraphicComposite graphic1(graph1);\r\n    GraphicComposite graphic2(graph2);\r\n    GraphicComposite graphic(graph3);\r\n\r\n    graphic1.add(<span style=\"color: #555555;\">&amp;<\/span>ellipse1);\r\n    graphic1.add(<span style=\"color: #555555;\">&amp;<\/span>ellipse2);\r\n    graphic1.add(<span style=\"color: #555555;\">&amp;<\/span>ellipse3);\r\n\r\n    graphic2.add(<span style=\"color: #555555;\">&amp;<\/span>ellipse4);\r\n\r\n    graphic.add(<span style=\"color: #555555;\">&amp;<\/span>graphic1);\r\n    graphic.add(<span style=\"color: #555555;\">&amp;<\/span>graphic2);\r\n\r\n    graphic1.print();\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    graphic2.print();\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    graphic.print();                                       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/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    graphic.remove(<span style=\"color: #555555;\">&amp;<\/span>graphic1);\r\n    graphic.print();                                       <span style=\"color: #0099ff; font-style: italic;\">\/\/ (7)<\/span>\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>In this example <code>Graphic<\/code> defines the interface for all concrete components.&nbsp; <code>GraphicComposite<\/code> stands for the composite node and <code>Ellipse<\/code> stands for the leaf node. <code>GraphicComposite<\/code> holds its children in a<code> std::vector&lt;const Graphic*&gt;<\/code> (line 1), and supports operations to add and remove children (lines 2 and 3).&nbsp;<\/p>\n<p>Each component has to implement the pure virtual function <code>print<\/code>. The <code>Ellipse<\/code> displays it <code>name<\/code> (line 4). The <code>GraphicComposite<\/code> also displays its <code>name<\/code> but, additionally, delegates the show call to its children (line 5).<\/p>\n<p>The main program creates a tree structure with the root <code>graphic<\/code>. First, the tree <code>graphic<\/code> is displayed with the subtree <code>graphic1<\/code> (line 6) and then without it (line 7).<\/p>\n<div class=\"moz-signature\">The following screenshot shows the output of the program:<\/div>\n<div class=\"moz-signature\">&nbsp;<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-6469\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/composite.png\" alt=\"composite\" width=\"600\" height=\"225\" style=\"display: block; margin-left: auto; margin-right: auto;\" moz-do-not-send=\"false\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/composite.png 756w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2022\/10\/composite-300x112.png 300w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<div class=\"moz-signature\">&nbsp;<\/div>\n<div>\n<h3>Known Uses<\/h3>\n<p>Applying an algorithm such as <span style=\"font-family: Courier New, Courier, monospace;\">find <\/span>or <span style=\"font-family: Courier New, Courier, monospace;\">find_if <\/span>on a container of the Standard Template Library can be regarded as a simplified application of the Composite Pattern. This is particularly true if the container is an ordered associative container like<span style=\"font-family: Courier New, Courier, monospace;\"> std::map.<\/span><\/p>\n<h3>Related Patterns<\/h3>\n<ul>\n<li>The<a href=\"https:\/\/en.wikipedia.org\/wiki\/Decorator_pattern\"> Decorator Pattern<\/a> is structurally similar to the composite. 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;<\/li>\n<li>The<a href=\"https:\/\/en.wikipedia.org\/wiki\/Iterator_pattern\"> Iterator Pattern<\/a> is typically used to traverse the components of the tree.<\/li>\n<li>The <a href=\"https:\/\/en.wikipedia.org\/wiki\/Visitor_pattern\">Visitor Pattern<\/a> encapsulates operations in objects applied to the components of the tree.<\/li>\n<\/ul>\n<\/div>\n<div>&nbsp;<\/div>\n<div class=\"moz-signature\">What are the pros and cons of the Composite Pattern?<\/div>\n<div class=\"moz-signature\">\n<h3>Pros and Cons<\/h3>\n<p>Let me start with the benefits.<\/p>\n<h4>Pros<\/h4>\n<ul>\n<li>Thanks to polymorphism and recursion, you can treat complex tree structures uniformly<\/li>\n<li>It is pretty easy to extend the tree structure with new components<\/li>\n<\/ul>\n<h4>Cons<\/h4>\n<ul>\n<li>Each new operation on the component must be implemented on the leaf node and the composite node<\/li>\n<li>The delegation of operations adds additional run-time costs<\/li>\n<\/ul>\n<h2>What&#8217;s Next?<\/h2>\n<p>With the Facade Pattern, the book &#8220;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Design_Patterns\">Design Patterns: Elements of Reusable Object-Oriented Software<\/a>&#8221; provides an additional structural pattern.&nbsp; The intention of the Facade Pattern is to provide a simplified interface to a complex library or framework.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<\/div>\n<div class=\"moz-signature\">&nbsp;<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Composite Pattern allows you to compose objects into tree structures and treat the individual object and composite objects uniformly.<\/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-6470","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\/6470","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=6470"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/6470\/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=6470"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=6470"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=6470"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}