
{"id":16,"date":"2014-07-22T12:17:29","date_gmt":"2014-07-22T12:17:29","guid":{"rendered":"http:\/\/www.codergears.com\/Blog\/?p=16"},"modified":"2015-09-04T23:23:31","modified_gmt":"2015-09-04T23:23:31","slug":"spring-the-art-of-using-grasp-patterns","status":"publish","type":"post","link":"https:\/\/codergears.com\/Blog\/?p=16","title":{"rendered":"Learn some basic design principles from GRASP: Spring case study."},"content":{"rendered":"<p>A design pattern is\u00a0a general reusable solution to a commonly occurring problem within a given context in software design. Patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system.<\/p>\n<p>\u201cGang of Four\u201d patterns are maybe the most popular ones. However, there are some basic design principles not well-known by developers, it&#8217;s the\u00a0General Responsibility Assignment Software Principles, abbreviated\u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/GRASP_(object-oriented_design)\" target=\"_blank\">GRASP<\/a>.<\/p>\n<p>GRASP consists of guidelines for assigning responsibility to classes and objects in object-oriented design. In this article we will discover the use of \u00a0these principles in the Spring framework.<\/p>\n<p><a href=\"http:\/\/www.springsource.org\/\" target=\"_blank\">Spring<\/a> is one of the most popular application development framework for enterprise Java.<br \/>\nThe Spring Framework does not impose any specific programming model, it has become popular in the Java community as an alternative to, replacement for, or even addition to the Enterprise JavaBean (EJB) model.<\/p>\n<p>Spring makes things easy for software designers, it gives them a good basis to have a well-designed projects. But what about Spring itself it\u2019s well designed as well?<br \/>\nTo try answering this question let\u2019s X-Ray some Spring jars with <a href=\"http:\/\/www.jarchitect.com\">JArchitect\u00a0<\/a><span style=\"color: #000000;\">and discover some of its\u00a0design facts.<\/span><\/p>\n<p>After the analysis here\u2019s the dependency graph between all Spring jars analyzed:<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img1.png\" alt=\"\" \/><\/p>\n<p>The <a href=\"http:\/\/www.jarchitect.com\/Doc_Matrix\">Matrix view<\/a> gives us more details about the dependency weight between these jars.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img2.png\" alt=\"\" \/><\/p>\n<h2>GRASP Principles<\/h2>\n<h2>Coupling<\/h2>\n<p>The loose coupling is desirable because a change in one area of an application will require less changes throughout the entire application. In the long run, this could alleviate a lot of time, effort, and cost associated with modifying and adding new features to an application.<\/p>\n<p>Using interfaces and abstract classes can improve the loose coupling and we can evaluate the abstractness of a defined module by the following metric:<\/p>\n<pre>A = Na \/ Nc\r\nWhere:\r\n* A = abstractness of a module\r\nZero is a completely concrete module. One is a completely abstract module.\r\n* Na = number of abstract classes in the module.\r\n* Nc = number of concrete classes in the module.\r\n<\/pre>\n<p>Here\u2019s the abstractness of all Spring jars analyzed:<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img3.png\" alt=\"\" \/><\/p>\n<p>Let\u2019s discover all interfaces of the jars analyzed, for that we can execute the following query:<\/p>\n<blockquote><p><span style=\"color: #3366ff;\">SELECT TYPES WHERE<\/span> IsInterface<\/p><\/blockquote>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img4.png\" alt=\"\" \/><\/p>\n<p>With a good abstractness ratio, and many interfaces used we can say that Spring enforces low coupling, what\u00a0makes it very flexible.<\/p>\n<h4><strong>High cohesion<\/strong><\/h4>\n<p style=\"color: #474747;\">The single responsibility principle states that a class should not 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 LCOM HS (HS stands for Henderson-Sellers) takes its values in the range [0-2]. A LCOM HS value highest than 1 should be considered alarming. Here are algorithms used to compute LCOM metrics:<\/p>\n<ul class=\"starlist\" style=\"color: #474747;\">\n<li style=\"font-weight: inherit; font-style: inherit;\">LCOM = 1 \u2013 (sum(MF)\/M*F)<\/li>\n<li style=\"font-weight: inherit; font-style: inherit;\">LCOM HS = (M \u2013 sum(MF)\/F)(M-1)<\/li>\n<\/ul>\n<ul class=\"starlist\" style=\"color: #474747;\">Where:<\/ul>\n<ul class=\"starlist\" style=\"color: #474747;\">\n<li style=\"font-weight: inherit; font-style: inherit;\">M is the number of methods in class (both static and instance methods are counted, it includes also constructors, properties getters\/setters, events add\/remove methods).<\/li>\n<li style=\"font-weight: inherit; font-style: inherit;\">F is the number of instance fields in the class.<\/li>\n<li style=\"font-weight: inherit; font-style: inherit;\">MF is the number of methods of the class accessing a particular instance field.<\/li>\n<li style=\"font-weight: inherit; font-style: inherit;\">Sum(MF) is the sum of MF over all instance fields of the class.<\/li>\n<\/ul>\n<p><span style=\"color: #474747;\">The underlying idea behind these formulas can be stated as follow: a class is utterly cohesive if all its methods use all its instance fields, which means that sum(MF)=M*F and then LCOM = 0 and LCOMHS = 0.\u00a0<\/span><\/p>\n<p>LCOMHS value higher than 1 should be considered alarming.<\/p>\n<blockquote><p><span style=\"color: #3333ff;\">SELECT TYPES WHERE<\/span> LCOMHS &gt; 0.95 <span style=\"color: #3333ff;\">AND <\/span>NbFields &gt; 10 <span style=\"color: #3333ff;\">AND <\/span>NbMethods &gt;10<\/p><\/blockquote>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img8.png\" alt=\"\" \/><\/p>\n<p>Only 4 classes are considered as not cohesive.<\/p>\n<h4>\u00a0<strong>Creator<\/strong><\/h4>\n<p>When we use interfaces, one interesting question is: who is responsible of creating concrete implementations? Spring provides a good solution using dependency injection, but it\u2019s not the way used inside Spring itself. Spring use Factories to acheive\u00a0this job, and as you can see it implements\u00a0many factory classes:<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img7.png\" alt=\"\" \/><\/p>\n<h4><strong>Information Expert<\/strong><\/h4>\n<p>Information Expert is a principle used to determine where to delegate responsibilities. These responsibilities include methods, computed fields and so on.<br \/>\nUsing the principle of Information Expert a general approach to assigning responsibilities is to look at a given responsibility, determine the information needed to fulfill it, and then determine where that information is stored.<\/p>\n<p>The Efferent Coupling metric can be an interesting metric to evaluate if some types has more responsibilities, The Efferent Coupling for a particular type is the number of types it directly depends on.<\/p>\n<p><span style=\"color: #474747;\">Types where the efferent coupling\u00a0\u00a0is more than 50 are types that depends on too many other types. They are complex and have more than one responsibility. They are good candidate for refactoring.<\/span><\/p>\n<blockquote><p><span style=\"color: #3366ff;\">SELECT TYPES WHERE<\/span> TypeCe &gt; 50<\/p><\/blockquote>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img9.png\" alt=\"\" \/><\/p>\n<h4><strong>Polymorphism<\/strong><\/h4>\n<p>According to Polymorphism, responsibility of defining the variation of behaviors based on type is assigned to the types for which this variation happens. This is achieved using polymorphic operations.<\/p>\n<p>Let\u2019s search for all polymorph methods, for that we can execute the following request:<\/p>\n<blockquote><p><span style=\"color: #3366ff;\">SELECT METHODS WHERE<\/span> NbOverloads&gt;1<\/p><\/blockquote>\n<p>The Metric view\u00a0gives us a good idea of using polymorphism inside Spring. In the Metric View, the code base is represented through a Treemap. Treemapping is a method for displaying tree-structured data by using nested rectangles. The tree structure used \u00a0is the usual code hierarchy:<\/p>\n<ul style=\"color: #555555;\">\n<li>Java projects contains packages<\/li>\n<li>Packages contains types<\/li>\n<li>Types contains methods and fields<\/li>\n<\/ul>\n<p style=\"color: #555555;\"><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img10.png\" alt=\"\" \/><\/p>\n<h4><strong>Protected Variations<\/strong><\/h4>\n<p>The Protected Variations pattern protects elements from the variations on other elements (objects, systems, subsystems) by wrapping the focus of instability with an interface and using polymorphism to create various implementations of this interface.<br \/>\nThe \u201cAbstractness vs Instability\u201d graph can be useful to detect projects that will be difficult to change.<\/p>\n<p><img decoding=\"async\" class=\"bordered\" src=\"..\/img\/spring\/img11.png\" alt=\"\" \/><\/p>\n<p style=\"color: #555555;\">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 style=\"color: #555555;\">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>Almost all spring jars are inside the green zone, it\u2019s a good point when changes are needed for maintenance or evolution.<\/p>\n<h2>Conclusion<\/h2>\n<p>Spring uses all the GRASP principles, what\u00a0makes it simple to understand and maintain, and developers can learn interesting design choices\u00a0\u00a0when discovering and analyzing the Spring source code.<\/p>\n<p>So give a look inside the source and enjoy with all design best practices implemented.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A design pattern is\u00a0a general reusable solution to a commonly occurring problem within a given context in software design. Patterns are formalized best practices that the programmer can use to solve common problems when designing an application or system. \u201cGang of Four\u201d patterns are maybe the most popular ones. However, there are some basic design &hellip; <a href=\"https:\/\/codergears.com\/Blog\/?p=16\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Learn some basic design principles from GRASP: Spring case study.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-16","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":19,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":2130,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions\/2130"}],"wp:attachment":[{"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codergears.com\/Blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}