{"id":296,"date":"2018-01-30T13:54:13","date_gmt":"2018-01-30T13:54:13","guid":{"rendered":"http:\/\/cppdepend.com\/blog\/?p=296"},"modified":"2018-02-09T17:58:23","modified_gmt":"2018-02-09T17:58:23","slug":"two-easy-approach-to-leverage-your-c-oop-design-skills","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/two-easy-approach-to-leverage-your-c-oop-design-skills\/","title":{"rendered":"Two easy approaches to leverage your C++ OOP design skills."},"content":{"rendered":"<p>Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa. Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability. The goal of this case study is to show the benefits of loose coupling and high cohesion, and how it can be implemented with C++. The case study consists of designing an application that accesses a file in order to get data, processes it, and prints the result to an output file.<!--more--><\/p>\n<h2>Solution with a lack of design<\/h2>\n<p>For this first design\u00a0 only one\u00a0 class named\u00a0<code>CDataProcessor<\/code>\u00a0is used to:<\/p>\n<ul>\n<li>Get data from a file.<\/li>\n<li>Process the data.<\/li>\n<li>Print the result.<\/li>\n<\/ul>\n<p>And the main method invokes the methods of this class.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.codeproject.com\/KB\/architecture\/LowCouplgHighCohesnCPP\/c1.PNG\" width=\"252\" height=\"265\" \/><\/p>\n<h2>Drawback of this solution<\/h2>\n<ul>\n<li>Low cohesion: The\u00a0<code>CDataProcessor<\/code>\u00a0class has many responsibilities, so we can\u2019t easily reuse the algorithm in other applications.<\/li>\n<li>High coupling: the processing is high coupled with the console and also with the data provider.<\/li>\n<\/ul>\n<h2>Design refactoring<\/h2>\n<h4>High cohesion<\/h4>\n<p>To improve the cohesion, each responsibility must be assigned to a different class, so we need three classes:<\/p>\n<ul>\n<li><code>CFileProvider<\/code>: To get data from a file.<\/li>\n<li><code>CDataProcessing<\/code>: To process data, and this class can use other classes to complete the processing, but to simplify the design, we consider that&#8217;s sufficient for our processing.<\/li>\n<li><code>CResultReporting<\/code>: To report result to a file.<\/li>\n<\/ul>\n<p>So each class has its own responsibility. The advantages of this design are:<\/p>\n<ul>\n<li>Easy to understand the classes.<\/li>\n<li>Easy to maintain.<\/li>\n<li>Easy to reuse the classes in other applications.<\/li>\n<\/ul>\n<h4>Low coupling<\/h4>\n<p>What happens if data exists in a database rather than a file? In our last design, our application is high coupled with a file provider.<\/p>\n<p>To resolve this problem, we need an interface that provide methods to get data from anywhere, and for the case of the file, we need a class that implement this interface.<\/p>\n<p>For that, using\u00a0<a href=\"http:\/\/en.wikibooks.org\/wiki\/More_C%2B%2B_Idioms\/Non-Virtual_Interface\">NVI<\/a>\u00a0can be good solution. This pattern is more useful than using only abstract classes because it&#8217;s possible to define a pre- and post-condition. It&#8217;s a useful object-oriented programming technique, particularly at development time. Pre- and post-conditions ensure that invariants of a class hierarchy (and in general, an abstraction) are not violated at designated points during execution of a program.<\/p>\n<p>In our case, we can add the\u00a0<code>IDataProvider<\/code>\u00a0interface.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.codeproject.com\/KB\/architecture\/LowCouplgHighCohesnCPP\/ClassDiagram1.png\" width=\"187\" height=\"292\" \/><\/p>\n<p>And\u00a0<code>CFileProvider<\/code>\u00a0inherits from\u00a0<code>IDataProvider<\/code>\u00a0to implement\u00a0<code>GetDataFromImpl<\/code>, and the same design can be used for\u00a0<code>CDataProcessing<\/code>\u00a0and\u00a0<code>CReportResult<\/code>.<\/p>\n<p>Here\u2019s the new collaboration between the classes after refactoring:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.codeproject.com\/KB\/architecture\/LowCouplgHighCohesnCPP\/c2.PNG\" width=\"467\" height=\"265\" \/><\/p>\n<h4>Class factory<\/h4>\n<p>In the latest design, the creation of the concrete instances of\u00a0<code>IDataProvider<\/code>,\u00a0<code>IDataProcessing<\/code>, and\u00a0<code>IReportResult<\/code>\u00a0are created by the main method. A better approach is to assign this responsibility to a factory class, so a logic to instantiate a family of instances needed is isolated.<\/p>\n<h4>Controller<\/h4>\n<p>The orchestration between all classes is implemented in the main method. It&#8217;s better to assign this responsibility to a Controller class, so we can use it in other applications.<\/p>\n<p>The controller needs three classes to interact with them, so the question is how do we bind instances to the controller.<\/p>\n<p>We can bind the instances using these two\u00a0approach:<\/p>\n<ul>\n<ul>\n<li>Add a method named\u00a0\u00a0<code>BindInstances(IDataProviderPtr,IDataProcesingPtr,IReportResultPtr)<\/code>.<\/li>\n<li>Define the Controler as template and the controller will be instantiated like that:<\/li>\n<\/ul>\n<\/ul>\n<pre id=\"pre60907\" class=\"notranslate\" lang=\"C++\">CController&lt;CFileProvider,CDataProcessor,CConsoleReport&gt;<\/pre>\n<p>The difference between the two solutions is that for the first one, each Data Provider must inherit from\u00a0<code>IDataProvider<\/code>, and for the second one,\u00a0<code>CFileProvider<\/code>\u00a0only needs the method\u00a0<code>GetData(Data&amp;)<\/code>\u00a0even if it\u2019s inherited from another class than\u00a0<code>IDataProvider<\/code>.<\/p>\n<p>There are many discussions between C++ gurus about using OOP or templates. Here&#8217;s a good\u00a0<a href=\"http:\/\/www.artima.com\/cppsource\/type_erasure.html\">article<\/a>\u00a0about this tension between the two approaches.<\/p>\n<p>Here\u2019s the new collaboration between the classes after the refactoring:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.codeproject.com\/KB\/architecture\/LowCouplgHighCohesnCPP\/c3.PNG\" width=\"589\" height=\"252\" \/><\/p>\n<h2>Benefits of the refactoring<\/h2>\n<p>After refactoring, this application became more flexible and we can use it for different scenarios:<\/p>\n<ul>\n<li>Can get data from file, database, XML file, CSV file, \u2026<\/li>\n<li>Can process with many classes not just one.<\/li>\n<li>Can report to console, file, \u2026<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Coupling is usually contrasted with cohesion. Low coupling often correlates with high cohesion, and vice versa. Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability. The goal of this case study is to show &hellip; <a href=\"https:\/\/cppdepend.com\/blog\/two-easy-approach-to-leverage-your-c-oop-design-skills\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Two easy approaches to leverage your C++ OOP design skills.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[32,13],"class_list":["post-296","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-code-quality","tag-cpp"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/comments?post=296"}],"version-history":[{"count":4,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions"}],"predecessor-version":[{"id":300,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/296\/revisions\/300"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}