{"id":1152,"date":"2020-06-05T00:06:58","date_gmt":"2020-06-04T14:06:58","guid":{"rendered":"http:\/\/www.moneystock.net\/wp_e\/?p=1152"},"modified":"2020-06-05T00:37:43","modified_gmt":"2020-06-04T14:37:43","slug":"design-pattern-composite","status":"publish","type":"post","link":"https:\/\/moneystock.net\/wp_e\/2020\/06\/05\/design-pattern-composite\/","title":{"rendered":"Design Pattern &#8211; Composite"},"content":{"rendered":"<p>Let&#8217;s refactor further the previous code sample using the composite pattern.<\/p>\n<p>See the link(https:\/\/www.dofactory.com\/net\/composite-design-pattern) for the details of what is a composite pattern.<\/p>\n<p>Let&#8217;s bring back the last code here.<\/p>\n<pre class=\"prettyprint\">                var availableCommands = new ICommand[]\r\n                {\r\n                    new UpdatePrice(_stockPriceManager, stocksToRead, _appSettings.DaysToReadFromWeb),\r\n                    new UpdateStats(_stockPriceManager, stocksToAnalyze),\r\n                    new SimulateCommand(_stockPriceManager, stocksToAnalyze, _marketWatchRepository, investDay,\r\n                        _tradeOption, _logger, _appSettings)\r\n                };\r\n\r\n                if (runOption == \"all\")\r\n                {\r\n                    availableCommands.Select(async c =&gt; await c.Execute());\r\n                }\r\n                else\r\n                {\r\n                    var command = availableCommands.Single(c =&gt; c.Name == runOption);\r\n                    await command.Execute();\r\n                }<\/pre>\n<p>&nbsp;<\/p>\n<p>In the previous sample, all individual commands executed by comparing the command name. However, we had to manually compare the string &#8220;all&#8221; in the if-else statement.<\/p>\n<p>By implementing the composite pattern, we can remove if-else entirely as below. Instead, we can create an AllCommands object, which is an implementation of ICommand. and add that group of command objects (allCommands) into the availableCommands variable.<\/p>\n<pre class=\"prettyprint\">                var availableCommands = new List&lt;ICommand&gt;\r\n                {\r\n                    new UpdatePrice(_stockPriceManager, stocksToRead, _appSettings.DaysToReadFromWeb),\r\n                    new UpdateStats(_stockPriceManager, stocksToAnalyze),\r\n                    new SimulateCommand(_stockPriceManager, stocksToAnalyze, _marketWatchRepository, investDay,\r\n                        _tradeOption, _logger, _appSettings)\r\n                };\r\n\r\n                var allCommands = new AllCommands()\r\n                {\r\n                    commands = availableCommands\r\n                };\r\n\r\n                availableCommands.Add(allCommands);\r\n\r\n                var command = availableCommands.Single(c =&gt; c.Name == commandName);\r\n                await command.Execute();<\/pre>\n<p>&nbsp;<\/p>\n<p>The key concept is making a group of individual commands as the same interface to the individual command so as to treat a group of commands as a command. Potentially, we can add a group of the group easily using this composite pattern otherwise the original if-else code could have been very messy.<\/p>\n<p>The AllCommands class looks like below. As explained, the key is having a list of ICommand inside of ICommand implementation.<\/p>\n<pre class=\"prettyprint\">    public class AllCommands : ICommand\r\n    {\r\n        public List&lt;ICommand&gt; commands { get; set; }\r\n        public string Name =&gt; \"All\";\r\n\r\n        public Task Execute()\r\n        {\r\n            commands.ForEach(async c =&gt; await c.Execute());\r\n\r\n            return Task.CompletedTask;\r\n        }\r\n    }<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let&#8217;s refactor further the previous code sample using the composite pattern. See the link(https:\/\/www.dofactory.com\/net\/composite-design-pattern) for the details of what is a composite pattern. Let&#8217;s bring back the last code here. var availableCommands = new ICommand[] { new UpdatePrice(_stockPriceManager, stocksToRead, _appSettings.DaysToReadFromWeb), new UpdateStats(_stockPriceManager, stocksToAnalyze), new SimulateCommand(_stockPriceManager, stocksToAnalyze, _marketWatchRepository, investDay, _tradeOption, _logger, _appSettings) }; if (runOption ==&hellip; <a class=\"more-link\" href=\"https:\/\/moneystock.net\/wp_e\/2020\/06\/05\/design-pattern-composite\/\">Continue reading <span class=\"screen-reader-text\">Design Pattern &#8211; Composite<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[548],"tags":[573,571],"class_list":["post-1152","post","type-post","status-publish","format-standard","hentry","category-c","tag-composite-pattern","tag-design-pattern","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1152","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/comments?post=1152"}],"version-history":[{"count":8,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1152\/revisions"}],"predecessor-version":[{"id":1160,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1152\/revisions\/1160"}],"wp:attachment":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/media?parent=1152"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/categories?post=1152"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/tags?post=1152"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}