{"id":434,"date":"2018-02-22T00:02:06","date_gmt":"2018-02-22T00:02:06","guid":{"rendered":"http:\/\/cppdepend.com\/blog\/?p=434"},"modified":"2018-11-07T16:51:07","modified_gmt":"2018-11-07T16:51:07","slug":"learn-from-the-c-poco-libraries-how-to-write-a-clean-code","status":"publish","type":"post","link":"https:\/\/cppdepend.com\/blog\/learn-from-the-c-poco-libraries-how-to-write-a-clean-code\/","title":{"rendered":"Learn from the C++ POCO libraries how to write a clean code."},"content":{"rendered":"<p>The\u00a0<a href=\"http:\/\/pocoproject.org\/\">POCO C++<\/a>\u00a0Libraries are a collection of open source class libraries for developing network-centric, portable applications in C++.<\/p>\n<p>POCO stands for POrtable COmponents. The libraries cover functionality such as threads, thread synchronization, file system access, streams, shared libraries and class loading, sockets and network protocols (HTTP, FTP, SMTP, etc.), and include an HTTP server, as well as an XML parser with SAX2 and DOM interfaces and SQL database access.<\/p>\n<p>The modular and efficient design and implementation makes the POCO C++ Libraries well suited for embedded development.<!--more--><span id=\"more-81\"><\/span><\/p>\n<p>Let&#8217;s explore a code snippet from the POCO source code:<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.cppdepend.com\/img\/poco.png\" \/><\/p>\n<p>This implementation\u00a0is characterized by:<\/p>\n<ul>\n<li>The function has few parameters.<\/li>\n<li>Assert technique is used to check if the entries are OK.<\/li>\n<li>The \u00a0variable naming is easy to understand.<\/li>\n<li>The method is short.<\/li>\n<li>\u00a0No extra comments in the body.The code explains itself.<\/li>\n<li>The function body is well indented.<\/li>\n<li>The well validated STL library is used when needed.<\/li>\n<\/ul>\n<p>If we\u00a0navigate across the POCO source code we can remark the coherence of the implementation. The same best practices rules are applied to each function.<\/p>\n<p>Let\u2019s take a look inside POCO using\u00a0<a href=\"http:\/\/www.cppdepend.com\/\">CppDepend\u00a0<\/a>and discover some facts about its design and its implementation .<\/p>\n<h2>DESIGN<\/h2>\n<h4>ABSTRACT VS INSTABILITY<\/h4>\n<p>Robert C.Martin wrote an interesting\u00a0<a href=\"http:\/\/www.objectmentor.com\/resources\/articles\/oodmetrc.pdf\">article\u00a0<\/a>about a set of metrics that can be used to measure the quality of an object-oriented design in terms of the interdependence between the subsystems of that design.<\/p>\n<p>Here\u2019s from the article what he said about the interdependence between modules:<\/p>\n<blockquote><p>What is it that makes a design rigid, fragile and difficult to reuse. It is the interdependence of the subsystems within that design. A design is rigid if it cannot be easily changed. Such rigidity is due to the fact that a single change to heavily interdependent software begins a cascade of changes in dependent modules. When the extent of that cascade of change cannot be predicted by the designers or maintainers the impact of the change cannot be estimated. This makes the cost of the change impossible to estimate. Managers, faced with such unpredictability, become reluctant to authorize changes. Thus the design becomes rigid.<\/p><\/blockquote>\n<p>And to fight the rigidity he introduce metrics like Afferent coupling, Efferent coupling, Abstractness, Instability and the \u201cdistance from main sequence\u201d and the \u201cAbstractness vs Instability\u201d graph.<\/p>\n<p>The \u201cAbstractness vs Instability\u201d graph can be useful to identify the projects\u00a0 difficult to maintain and evolve. Here\u2019s the \u201cAbstractness vs Instability\u201d graph of the POCO library:<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img9.png\" alt=\"\" width=\"500px\" \/><\/p>\n<p>The idea behind this graph is that the more a code element of a program is popular, the more it should be abstract. Or in other words, avoid depending too much directly on implementations, depend on abstractions instead. By popular code element I mean a project (but the idea works also for packages and types) that is massively used by other projects of the program.<br \/>\nIt is not a good idea to have concrete types very popular in your code base. This provokes some Zones of Pains in your program, where changing the implementations can potentially affect a large portion of the program. And implementations are known to evolve more often than abstractions.<\/p>\n<p>The main sequence line (dotted) in the above diagram shows the how abstractness and instability should be balanced. A stable component would be positioned on the left. If you check the main sequence you can see that such a component should be very abstract to be near the desirable line \u2013 on the other hand, if its degree of abstraction is low, it is positioned in an area that is called the \u201czone of pain\u201d.<\/p>\n<p>Only the Fondation project is inside the zone of pain , it\u2019s normal because it\u2019s very used by other projects.<\/p>\n<p>[adrotate banner=&#8221;3&#8243;]<\/p>\n<h4>INHERITANCE<\/h4>\n<p>Multiple inheritance increase the complexity and\u00a0it&#8217;s better to use it carefully.<\/p>\n<p>Let\u2019s search for all classes with many base classes.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query7.jpg\" alt=\"\" \/><\/p>\n<p>The blue rectangles represent the result.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img10.png\" alt=\"\" \/><\/p>\n<p>Only few classes derived from more than one class.<\/p>\n<h4>TYPE COHESION<\/h4>\n<p>The single responsibility principle states that a class should have more than one reason to change. Such a class is said to be cohesive. A high LCOM value generally pinpoints a poorly cohesive class. There are several LCOM metrics. The LCOM takes its values in the range [0-1]. The LCOMHS (HS stands for Henderson-Sellers) takes its values in the range [0-2]. Note that the LCOMHS metric is often considered as more efficient to detect non-cohesive types. LCOMHS value higher than 1 should be considered alarming.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query8.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img11.png\" alt=\"\" \/><\/p>\n<p>Only 1% of types are considered as no cohesive.<\/p>\n<h4>EFFERENT COUPLING<\/h4>\n<p>The Efferent Coupling for a particular type is the number of types it directly depends on.<br \/>\nTypes where TypeCe &gt; 50 are types that depends on too many other types. They are complex and have more than one responsability. They are good candidate for refactoring.<\/p>\n<p>Let\u2019s execute the following CQLinq request.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query9.jpg\" alt=\"\" \/><\/p>\n<p>And the result is empty so no class has many responsibilities.<\/p>\n<h4>TYPES MOST USED<\/h4>\n<p>It\u2019s very interesting to know which types are most used,for that we can use the TypeRank metric.<\/p>\n<p>TypeRank values are computed by applying the Google PageRank algorithm on the graph of type\u2019s dependencies. A homothety of center 0.15 is applied to make it so that the average of TypeRank is 1.<\/p>\n<p>Types with high TypeRank should be more carefully tested because bugs in such types will likely be more catastrophic.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img12.png\" alt=\"\" \/><\/p>\n<p>Let\u2019s search for types most used and complex.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query10.jpg\" alt=\"\" \/><\/p>\n<p>The result is empty so no class is very used and complex.<\/p>\n<h4>LAYERING AND LEVEL METRIC<\/h4>\n<p>This\u00a0<a href=\"http:\/\/codebetter.com\/blogs\/patricksmacchia\/archive\/2008\/02\/10\/layering-the-level-metric-and-the-discourse-of-method.aspx\">post<\/a>\u00a0explain the level metric and how to exploit it to improve design.<\/p>\n<p>Let\u2019s search dependency cycles for that we can execute the following CQLinq request:<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query11.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img13.png\" alt=\"\" \/><\/p>\n<p>Only few methods has dependency cycle, let\u2019s take for example the Zip project and look to its dependency graph.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img14.png\" alt=\"\" \/><\/p>\n<p>Only 1 dependency cycle exist in this project.<\/p>\n<h2>POCO Implementation<\/h2>\n<h4><em>NUMBER OF LINE OF CODE<\/em><\/h4>\n<p>Methods with many number of line of code are not easy to maintain and understand, let\u2019s search for\u00a0 the methods with more than 60 lines.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query1.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img3.png\" alt=\"\" \/><\/p>\n<p>Less than 1% of methods has more than 60 lines.<\/p>\n<p>[adrotate banner=&#8221;3&#8243;]<\/p>\n<h4><em>CYCLOMATIC COMPLEXITY<\/em><\/h4>\n<p>Cyclomatic complexity is a popular procedural software metric equal to the number of decisions that can be taken in a procedure.<\/p>\n<p>Let\u2019s execute the following CQLinq request to detect methods to refactor.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query2.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img4.png\" alt=\"\" \/><\/p>\n<p>So only 1% of methods can be considered as complex.<\/p>\n<p><em>Which methods are complex and not enough commented?<\/em><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query3.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img5.png\" alt=\"\" \/><\/p>\n<h4><em>METHODS WITH MANY VARIABLES<\/em><\/h4>\n<p>Methods where NbVariables is higher than 8 are hard to understand and maintain. Methods where NbVariables is higher than 15 are extremely complex and should be split in smaller methods (except if they are automatically generated by a tool).<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query4.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img6.png\" alt=\"\" \/><\/p>\n<p>Only 8 methods has too many variables.<\/p>\n<h4><em>TYPES WITH MANY METHODS AND FIELDS<\/em><\/h4>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query5.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img7.png\" alt=\"\" \/><\/p>\n<p>Only 3% of types has many methods.<\/p>\n<p>And we can do the same search for fields<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/query6.jpg\" alt=\"\" \/><\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"http:\/\/www.cppdepend.com\/img\/poco\/img8.png\" alt=\"\" \/><\/p>\n<p>Less than 1% of types has many fields.<\/p>\n<p>We can say that POCO is well implemented, few methods are considered as complex, the types are simple with few methods and fields and it\u2019s well commented.<\/p>\n<h2><\/h2>\n<p>[adrotate banner=&#8221;3&#8243;]<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The\u00a0POCO C++\u00a0Libraries are a collection of open source class libraries for developing network-centric, portable applications in C++. POCO stands for POrtable COmponents. The libraries cover functionality such as threads, thread synchronization, file system access, streams, shared libraries and class loading, sockets and network protocols (HTTP, FTP, SMTP, etc.), and include an HTTP server, as well &hellip; <a href=\"https:\/\/cppdepend.com\/blog\/learn-from-the-c-poco-libraries-how-to-write-a-clean-code\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learn from the C++ POCO libraries how to write a clean code.&#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":[],"class_list":["post-434","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/434","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=434"}],"version-history":[{"count":9,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/434\/revisions"}],"predecessor-version":[{"id":1205,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/posts\/434\/revisions\/1205"}],"wp:attachment":[{"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/media?parent=434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/categories?post=434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cppdepend.com\/blog\/wp-json\/wp\/v2\/tags?post=434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}