{"id":36531,"date":"2023-03-24T19:16:00","date_gmt":"2023-03-24T16:16:00","guid":{"rendered":"https:\/\/symphony-solutions.com\/?p=36531"},"modified":"2024-05-02T12:13:18","modified_gmt":"2024-05-02T09:13:18","slug":"solid-principles-in-java","status":"publish","type":"post","link":"https:\/\/symphony-solutions.com\/insights\/solid-principles-in-java","title":{"rendered":"Solid Principles in Java\u00a0"},"content":{"rendered":"<div class=\"wp-block-spacer-sm\">\r\n  <div class=\"pb-2 pb-lg-4\"><\/div>\r\n<\/div>\n\n\n<p>What are the SOLID principles, why do we need them, and how to approach them correctly?&nbsp;<\/p>\n\n\n\n<p>In\u202fsoftware engineering, if you want to have understandable, flexible, and\u202fmaintainable object-oriented design SOLID principles is the direction to look at. SOLID\u202fis an acronym\u202ffor five design principles which are actually a subset of many principles promoted by American software engineer and instructor\u202fRobert C. Martin (also known as Uncle Bob). They were\u202ffirst introduced in his paper\u202fDesign Principles and Design Patterns in 2000. But the actual acronym was introduced later, in 2004, by Michael Feathers.&nbsp;<\/p>\n\n\n\n<p>Let&#8217;s look at each principle one by one. Following the SOLID acronym, they are:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The\u202fSingle Responsibility Principle&nbsp;<\/li>\n\n\n\n<li>The\u202fOpen-Closed Principle&nbsp;<\/li>\n\n\n\n<li>The\u202fLiskov Substitution Principle&nbsp;<\/li>\n\n\n\n<li>The\u202fInterface Segregation Principle&nbsp;<\/li>\n\n\n\n<li>The\u202fDependency Inversion Principle&nbsp;<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-single-principle\">The\u202fSingle Responsibility Principle&nbsp;<\/h2>\n\n\n\n<p>This principle states that \u201c<em>a class should have only one reason to change<\/em>\u201d which means every class should have a single responsibility or single job or single purpose.&nbsp;<\/p>\n\n\n\n<p>For instance, if we have a data model class, like let\u2019s say Athlete, with the list of fields related to that entity, the class should change only when we change the entity.&nbsp;<\/p>\n\n\n\n<p>Following Single Responsibility Principle benefits us in:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Testing \u2013 less job for a class \u2013 less test cases;&nbsp;<\/li>\n\n\n\n<li>Merge conflicts \u2013 less job for a class \u2013 less reasons to change a class \u2013 less merge conflicts&nbsp;<\/li>\n\n\n\n<li>Lower coupling \u2013 less job for a class \u2013 less dependencies&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>And just in general, it\u2019s easier to deal with small, well-organized classes, where it\u2019s pretty obvious what job the class does.&nbsp;<\/p>\n\n\n\n<p>But let\u2019s have a look what happens when we omit Single Responsibility Principle. Let\u2019s imagine that we have an app for GYM goers where a user can fill in his body parameters, like height and weight. They also can choose exercises, save their progress of adding weights in exercises, and also they can track their diet.&nbsp;<\/p>\n\n\n\n<p>Imagine there is a class AthleteService which handles athlete\u2019s progress in the GYM, keeps track of the diet, and creates the progress graph.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"615\" src=\"https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-1.png\" alt=\"solid_principles_in_java_article_1\" class=\"wp-image-37579\" srcset=\"https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-1.png 1024w, https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-1-300x180.png 300w, https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-1-768x461.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this case our class has several reasons to be changed whether our athlete is working out in the GYM and adding some weights to the barbell or he\/she is calculating the calories of their dinner, or they want to see the progress over period in the graph. We always go to the same class which is not a very good approach. But not only we are mixing up our gym and diet stuff in one class we are also mixing up our business and persistence logic which also violates Single Responsibility Principle.&nbsp;<\/p>\n\n\n\n<p>To achieve the goal of the single responsibility principle, we should implement separate classes that perform a single functionality only.&nbsp;<\/p>\n\n\n\n<p>For instance, for the GYM related stuff we will have BarbellWeightService\u2026&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"244\" src=\"https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-2.png\" alt=\"solid_principles_in_java_article_2\" class=\"wp-image-37580\" srcset=\"https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-2.png 1024w, https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-2-300x71.png 300w, https:\/\/symphony-solutions.com\/wp-content\/uploads\/sites\/5\/2023\/12\/image-2-768x183.png 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>and separately BarbellWeightPersistence.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/3-2-1024x222.png\" alt=\"solid_principles_in_java_article_3\"\/><\/figure>\n\n\n\n<p>And the same goes for the diet \u2013 NetCaloriesService\u2026&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/4-1024x221.png\" alt=\"solid_principles_in_java_article_4\"\/><\/figure>\n\n\n\n<p>and separately NetCaloriesPersistence.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/5-2-1024x223.png\" alt=\"solid_principles_in_java_article_5\"\/><\/figure>\n\n\n\n<p>And, of course, the separate class for creating the graphs \u2013 GraphService.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/6-1-1024x344.png\" alt=\"solid_principles_in_java_article_6\"\/><\/figure>\n\n\n\n<p>Now, as you can see, each class has its separate job to do which exactly what the first SOLID principle states.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"open-closed-principle\">The\u202fOpen-Closed Principle&nbsp;<\/h2>\n\n\n\n<p>This principle states that \u201c<em>software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification<\/em>\u201d which means you should be able to extend a class behavior, without modifying it.&nbsp;<\/p>\n\n\n\n<p>To understand this principle let\u2019s take a look at our last class which was the GraphService. I deliberately wrote it in a way that violates The\u202fOpen-Closed Principle. The class has a method which creates a graph depending of its type \u2013 weights or calories in our example. But imagine that we want to add to our app a graph that shows changes in body weight over period of time. In this case we would have to change our&nbsp; GraphService.&nbsp;<\/p>\n\n\n\n<p>To avoid this we should redesign a bit our GraphService. Instead of putting in the createProgressGraph method some business logic we should make an abstraction.&nbsp;<\/p>\n\n\n\n<p>And now the GraphService instead of being a class becomes an interface.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/7-1024x222.png\" alt=\"solid_principles_in_java_article_7\"\/><\/figure>\n\n\n\n<p>And we will have separate classes for creating the graphs of different types which will implement the GraphSrvice.&nbsp;&nbsp;<\/p>\n\n\n\n<p>BarbellWeightGraph&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/8-1024x248.png\" alt=\"solid_principles_in_java_article_8\"\/><\/figure>\n\n\n\n<p>CaloriesGraph&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/9-1024x244.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>And now when we want to add the body weight graph we simply add one more implementation of GraphService \u2013 BodyWeightGraph.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/10-1-1024x246.png\" alt=\"solid_principles_in_java_article_10\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"liskov-principle\">The\u202fLiskov Substitution Principle&nbsp;<\/h2>\n\n\n\n<p>This principle states that \u201c<em>Derived or child classes must be substitutable for their base or parent classes\u201d.\u202f<\/em>In other words, if class A is a subtype of class B, then we should be able to replace B with A without interrupting the behavior of the program.&nbsp;<\/p>\n\n\n\n<p>This principle is a bit trickier than others, so let\u2019s go directly to some code examples.&nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/11-1024x295.png\" alt=\"solid_principles_in_java_article_11\"\/><\/figure>\n\n\n\n<p>Here we have an abstract class SmartWatch and the list of methods which represent what a smart watch can do. And let\u2019s imagine that we have two smartwatches \u2013 Apple Watch and Garmin. Let\u2019s start with an Apple Watch.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/12-1024x591.png\" alt=\"solid_principles_in_java_article_12\"\/><\/figure>\n\n\n\n<p>An Apple Watch can do all the things that are represented by the methods in the abstract SmartWatch class, so we can say that both classes can replace each other without any issue for our program.&nbsp;&nbsp;<\/p>\n\n\n\n<p>And now let\u2019s have a look at a Garmin Watch. A Garmin Watch can receive a notification, but can\u2019t send a notification (at least mine can\u2019t). So having this type of a program design violates The\u202fLiskov Substitution Principle. What is the solution here? The solution lies in having instead of one abstract class with a list of all possible features several interfaces with separate features.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/13-1024x148.png\" alt=\"solid_principles_in_java_article_13\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/14-1024x149.png\" alt=\"solid_principles_in_java_article_14\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/15-1024x147.png\" alt=\"solid_principles_in_java_article_15\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/16-1024x147.png\" alt=\"solid_principles_in_java_article_16\"\/><\/figure>\n\n\n\n<p>And now our Apple Watch can simply implement all the interfaces and our Garmin watch can take only those interfaces which have feature available for it.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/17-1024x518.png\" alt=\"solid_principles_in_java_article_17\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"interface-principle\">The\u202fInterface Segregation Principle&nbsp;<\/h2>\n\n\n\n<p>This principle is fairly simple and it says that instead of having big interfaces with a list of different methods you should divide them into smaller ones, just with the specific behavior. In doing so we will avoid situations when we will be forced to implement features that we don\u2019t need. Let\u2019s get back to our GYM example and imagine having such interface.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/18-1024x298.png\" alt=\"solid_principles_in_java_article_18\"\/><\/figure>\n\n\n\n<p>In this case our GYM goer will be forced to do all these activities every time he enters the gym. Pretty sure he\/she won\u2019t be happy about this. To avoid this overtraining and violation of the Interface Segregation Principle we should split our GymGoer interface into four separate ones.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/19-1024x468.png\" alt=\"solid_principles_in_java_article_19\"\/><\/figure>\n\n\n\n<p>And now our athlete will be a lot happier to have the choice what to do in the gym and let\u2019s say he\/she decides that weight lifting and some cardio will be enough for today.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/20-1024x369.png\" alt=\"solid_principles_in_java_article_20\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"inversion-principle\">The\u202fDependency Inversion Principle&nbsp;<\/h2>\n\n\n\n<p>The last SOLID principle is also a bit harder to understand at the beginning and it states:&nbsp;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>We should depend on abstractions (interfaces and abstract classes) instead of concrete implementations (classes).&nbsp;&nbsp;<\/li>\n\n\n\n<li>The abstractions should not depend on details; instead, the details should depend on abstractions.&nbsp;<\/li>\n<\/ul>\n\n\n\n<p>To understand what all this means let\u2019s again look at some code examples and let\u2019s stick with our GYM app.&nbsp;<\/p>\n\n\n\n<p>First start with an example that violates The\u202fDependency Inversion Principle.&nbsp;<\/p>\n\n\n\n<p>We have three basic GYM exercises:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/21-1024x638.png\" alt=\"solid_principles_in_java_article_21\"\/><\/figure>\n\n\n\n<p>And now we can construct our workout routine using these exercises.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/22-1024x444.png\" alt=\"solid_principles_in_java_article_22\"\/><\/figure>\n\n\n\n<p>This simple class will work and our workout routine will definitely will make us stronger, but what if after some time we want to change the exercises or add some new ones. In this case we will be forced to change our WorkoutRoutine class which will violate The\u202fOpen-Closed Principle.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Also, the WorkoutRoutine class is a high-level module, and it depends on low-level modules such as SquatExercise, DeadLiftExercise, and BenchPressExercise. We are actually violating the first part of the Dependency Inversion Principle.&nbsp;<\/p>\n\n\n\n<p>Also, by inspecting the doWorkout method of WorkoutRoutine class, we realize that the methods doSquat, doDeadLift, and doBenchPress are methods bound to the corresponding classes. Regarding the workout routine scope, those are details since they are types of exercises. Thus, the second part of the Dependency Inversion Principle is violated.&nbsp;<\/p>\n\n\n\n<p>To fix these issues we need to add an abstraction, and in our case it will be an interface Exercise.&nbsp;&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/23-1024x173.png\" alt=\"solid_principles_in_java_article_23\"\/><\/figure>\n\n\n\n<p>And now we will change our classes that represent exercises.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/24-1024x319.png\" alt=\"solid_principles_in_java_article_24\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/25-1024x321.png\" alt=\"solid_principles_in_java_article_25\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/26-1024x319.png\" alt=\"solid_principles_in_java_article_26\"\/><\/figure>\n\n\n\n<p>And the final refactoring is in our WorkoutRoutine class.&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.symphony-solutions.eu\/wp-content\/uploads\/sites\/6\/2023\/03\/27-1024x419.png\" alt=\"solid_principles_in_java_article_27\"\/><\/figure>\n\n\n\n<p>What we achieved by all those changes is that the WorkoutRoutine class does not depend on lower level modules, but rather abstractions.\u202fAlso, low-level modules and their details depend on abstractions.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion&nbsp;<\/h2>\n\n\n\n<p>In this article we covered SOLID principles, we started with a bit of history and then one by one we went through all five principles with the code examples of cases that violate the principle and the solutions how to fix the issues. Hope you enjoyed the reading.&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What are the SOLID principles, why do we need them, and how to approach them correctly?&nbsp; In\u202fsoftware engineering, if you want to have understandable, flexible, and\u202fmaintainable object-oriented design SOLID principles is the direction to look at. SOLID\u202fis an acronym\u202ffor five design principles which are actually a subset of many principles promoted by American software engineer [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":36536,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[502],"tags":[],"technology":[],"service_tax":[],"product":[],"association":[],"class_list":["post-36531","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-insights"],"acf":[],"_links":{"self":[{"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/posts\/36531","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/comments?post=36531"}],"version-history":[{"count":0,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/posts\/36531\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/media\/36536"}],"wp:attachment":[{"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/media?parent=36531"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/categories?post=36531"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/tags?post=36531"},{"taxonomy":"technology","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/technology?post=36531"},{"taxonomy":"service_tax","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/service_tax?post=36531"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/product?post=36531"},{"taxonomy":"association","embeddable":true,"href":"https:\/\/symphony-solutions.com\/wp-json\/wp\/v2\/association?post=36531"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}