<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Anna</title>
    <description>The latest articles on Forem by Anna (@azaleamollis).</description>
    <link>https://forem.com/azaleamollis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F137547%2Fc1a8b893-39c7-4a5d-898e-cf4198421063.jpg</url>
      <title>Forem: Anna</title>
      <link>https://forem.com/azaleamollis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/azaleamollis"/>
    <language>en</language>
    <item>
      <title>Software documentation is part of accessibility</title>
      <dc:creator>Anna</dc:creator>
      <pubDate>Tue, 22 Oct 2019 22:49:49 +0000</pubDate>
      <link>https://forem.com/azaleamollis/software-documentation-is-part-of-accessibility-7o9</link>
      <guid>https://forem.com/azaleamollis/software-documentation-is-part-of-accessibility-7o9</guid>
      <description>&lt;p&gt;We mostly discuss accessibility as a way to enable people with disabilities to use a website or application. However, the accessibility needs of users who don't have any disabilities but experience other kinds of hardships are less widely discussed.&lt;/p&gt;

&lt;p&gt;The lack of knowledge on a given subject is such a hardship. Providing technical documentation that addresses this problem is also an essential part of accessibility, especially in the case of open-source development. Here, users don't only act as end-users but also might want to contribute to the code as developers.&lt;/p&gt;

&lt;p&gt;If you have ever had to use poorly documented software you know what I'm talking about. Boring, badly structured, and user-hostile documentation can make people give up on a tool, just like an overly complicated purchasing process can result in shopping cart abandonment on eCommerce websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two types of technical documentation
&lt;/h2&gt;

&lt;p&gt;Essentially, there are two types of technical documentation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;documentation created for end-users,&lt;/li&gt;
&lt;li&gt;documentation created for developers.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  End-user documentation
&lt;/h3&gt;

&lt;p&gt;Companies tend to focus more on end-user documentation. You can find &lt;a href="http://blog.screensteps.com/10-examples-of-great-end-user-documentation" rel="noopener noreferrer"&gt;nice and user-friendly examples&lt;/a&gt; of this kind of docs. However, even the best-designed end-user docs might lack crucial accessibility features such as sufficient color contrast or closed captioning.&lt;/p&gt;

&lt;p&gt;For instance, have a look at &lt;a href="https://www.salesforce.com/uk/learning-centre/" rel="noopener noreferrer"&gt;Salesforce's Learning Centre&lt;/a&gt;. Overall, they did a great job with the docs. The information is well-structured and logical, and the docs don't use too much technical jargon.&lt;/p&gt;

&lt;p&gt;However, if you take a closer look you will find that some crucial accessibility features are missing. For example, links are distinguished only by color rather than providing a &lt;a href="https://www.annalytic.com/link-accessibility-colors-not-enough.html" rel="noopener noreferrer"&gt;non-color designator&lt;/a&gt; such as an underline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlhmunkza41nf5zykiw8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frlhmunkza41nf5zykiw8.jpg" alt="Salesforce Learning Center" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer documentation
&lt;/h3&gt;

&lt;p&gt;Most technical documentation created for developers had been in a poor state for many years. They didn't simply lack accessibility features but also used unstructured text blocks, unreadable fonts and small line height, lacked table of contents, and were visually unappealing on the whole.&lt;/p&gt;

&lt;p&gt;The rise of video tutorials made the scene of developer docs much better. At about the same time, well-designed documentations began to appear.&lt;/p&gt;

&lt;p&gt;The first developer documentation I really liked was the &lt;a href="https://foundation.zurb.com/sites/docs/" rel="noopener noreferrer"&gt;Zurb Foundation Docs&lt;/a&gt;. It has improved a lot since I first saw it, but even the earlier versions were designed, written, and structured in a way that made me want to learn.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbebxr24026haspvz9yg8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbebxr24026haspvz9yg8.jpg" alt="Zurb Foundation Docs" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.atlassian.com/git/tutorials/what-is-version-control" rel="noopener noreferrer"&gt;Atlassian's Git Tutorials&lt;/a&gt; constitute another good example of user-friendly developer documentation. They are just as well-structured as the Foundation Docs but also come with great explanatory illustrations (in SVG!) and a &lt;a href="https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet" rel="noopener noreferrer"&gt;downloadable cheatsheet&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Both Foundation Docs and Git Tutorials present the information in a way that is accessible to users without much knowledge on the subject. Still, both have some accessibility issues that might be a problem for users with disabilities (e.g. color contrast problems).&lt;/p&gt;

&lt;h2&gt;
  
  
  Two levels of documentation accessibility
&lt;/h2&gt;

&lt;p&gt;Documentation accessibility has two levels that both end-user and developer docs should implement:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The docs need to be accessible for users without sufficient knowledge of the tool.&lt;/li&gt;
&lt;li&gt;The docs need to be accessible for users who may have different disabilities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The two levels can also intersect, as there can be users who are affected by both problems (i.e. don't have the sufficient knowledge plus have a disability).&lt;/p&gt;

&lt;p&gt;The three examples I mentioned in this article (Salesforce, Foundation, Atlassian) handle the first level of documentation accessibility really well, as they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;don't use technical jargon, or if they do they give the necessary explanation,&lt;/li&gt;
&lt;li&gt;provide menus/widgets/table of contents to ease navigation,&lt;/li&gt;
&lt;li&gt;structure pages (careful typography, enough white space, vertical rhythm, etc.),&lt;/li&gt;
&lt;li&gt;provide illustrations or instructional videos,&lt;/li&gt;
&lt;li&gt;provide examples of usage, demos, or code snippets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They also partially implement the second level of accessibility. However, you can still find issues here and there, such as color contrast, link visibility, or video captioning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;I don't know if perfectly accessible docs exist or not, but if they do they should implement both levels of documentation accessibility. It's certainly not something easy to accomplish, as there are so many things to pay attention to.&lt;/p&gt;

&lt;p&gt;However, documentation accessibility is still an important part of accessibility. First, because users with disabilities shouldn't be excluded from adopting new technologies, but also because it greatly impacts how many people are willing to go the extra mile to pick up a new tool.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>opensource</category>
      <category>technicalwriting</category>
      <category>documentation</category>
    </item>
    <item>
      <title>SOLID design principles: Building stable and flexible systems</title>
      <dc:creator>Anna</dc:creator>
      <pubDate>Wed, 20 Feb 2019 18:42:52 +0000</pubDate>
      <link>https://forem.com/azaleamollis/solid-design-principles-building-stable-and-flexible-systems--2ph7</link>
      <guid>https://forem.com/azaleamollis/solid-design-principles-building-stable-and-flexible-systems--2ph7</guid>
      <description>&lt;p&gt;To build stable and flexible software, we need to keep software design principles in mind. Having error-free code is essential. However, well-designed software architecture is just as important.&lt;/p&gt;

&lt;p&gt;SOLID is one of the most well-known sets of software design principles. It can help you avoid common pitfalls and think about your apps’ architecture from a higher level.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are SOLID design principles?
&lt;/h2&gt;

&lt;p&gt;SOLID design principles are five software design principles that enable you to write effective object-oriented code. Knowing about &lt;a href="https://raygun.com/blog/oop-concepts-java/" rel="noopener noreferrer"&gt;OOP principles&lt;/a&gt; like abstraction, encapsulation, inheritance, and polymorphism is important, but how would you use them in your everyday work? SOLID design principles have become so popular in recent years because they answer this question in a straightforward way.&lt;/p&gt;

&lt;p&gt;The SOLID name is a mnemonic acronym where each letter represents a software design principle, as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; S for Single Responsibility Principle&lt;/li&gt;
&lt;li&gt; O for Open/Closed Principle&lt;/li&gt;
&lt;li&gt; L for Liskov Substitution Principle&lt;/li&gt;
&lt;li&gt; I for Interface Segregation Principle&lt;/li&gt;
&lt;li&gt; D for Dependency Inversion Principle&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The five principles overlap here and there, and programmers use them broadly. SOLID principles lead to more flexible and stable software architecture that’s easier to maintain and extend, and less likely to break.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single Responsibility Principle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oodesign.com/single-responsibility-principle.html" rel="noopener noreferrer"&gt;Single Responsibility Principle&lt;/a&gt; is the first SOLID design principle, represented by the letter “S” and defined by &lt;a href="https://en.wikipedia.org/wiki/Robert_C._Martin" rel="noopener noreferrer"&gt;Robert C Martin&lt;/a&gt;. It states that in a well-designed application, each class (microservice, code module) should have only one single responsibility. Responsibility is used in the sense of having only one reason to change.&lt;/p&gt;

&lt;p&gt;When a class handles more than one responsibility, any changes made to the functionalities might affect others. This is bad enough if you have a smaller app but can become a nightmare when you work with &lt;a href="https://raygun.com/blog/errors-and-exceptions/" rel="noopener noreferrer"&gt;complex, enterprise-level software&lt;/a&gt;. By making sure that each module encapsulates only one responsibility, you can save a lot of testing time and create a more maintainable architecture.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example of the Single Responsibility Principle
&lt;/h4&gt;

&lt;p&gt;Let’s see an example. I’ll use Java but you can apply SOLID design principles to any other OOP languages, too.&lt;/p&gt;

&lt;p&gt;Say, we are writing a Java application for  a book store. We create a &lt;code&gt;Book&lt;/code&gt; class that lets users get and set the titles and authors of each book, and search the book in the inventory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchBook&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the above code violates the Single Responsibility Principle, as the &lt;code&gt;Book&lt;/code&gt; class has two responsibilities. First, it sets the data related to the books (&lt;code&gt;title&lt;/code&gt; and &lt;code&gt;author&lt;/code&gt;). Second, it searches for the book in the inventory. The setter methods change the &lt;code&gt;Book&lt;/code&gt; object, which might cause problems when we want to search the same book in the inventory.  &lt;/p&gt;

&lt;p&gt;To apply the Single Responsibility Principle, we need to decouple the two responsibilities. In the refactored code, the &lt;code&gt;Book&lt;/code&gt; class will only be responsible for getting and setting the data of the &lt;code&gt;Book&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getTitle&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getAuthor&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setAuthor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we create another class called &lt;code&gt;InventoryView&lt;/code&gt; that will be responsible for checking the inventory. We move the &lt;code&gt;searchBook()&lt;/code&gt; method here and reference the &lt;code&gt;Book&lt;/code&gt; class in the constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InventoryView&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

  &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;InventoryView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchBook&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the UML diagram below, you can see how the architecture changed after we refactored the code following the Single Responsibility Principle. We split the initial &lt;code&gt;Book&lt;/code&gt; class that had two responsibilities into two classes, each having its own single responsibility.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmvith5yn2owlz7lijc1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmvith5yn2owlz7lijc1.jpg" alt="Single Responsibility Principle" width="475" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Open/Closed Principle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oodesign.com/open-close-principle.html" rel="noopener noreferrer"&gt;Open/Closed Principle&lt;/a&gt; is the “O” of SOLID’s five software design principles. It was &lt;a href="https://en.wikipedia.org/wiki/Bertrand_Meyer" rel="noopener noreferrer"&gt;Bertrand Meyer&lt;/a&gt; who coined the term in his book “Object-Oriented Software Construction”. The Open/Closed Principle states that classes, modules, microservices, and other code units should be open for extension but closed for modification.&lt;/p&gt;

&lt;p&gt;So, you should be able to extend your existing code using OOP features like inheritance via subclasses and interfaces. However, you should never modify classes, interfaces, and other code units that already exist (especially if you use them in production), as it can lead to unexpected behavior. If you add a new feature by extending your code rather than modifying it, you minimize the risk of failure as much as possible. Besides, you also don’t have to unit test existing functionalities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of the Open/Closed Principle
&lt;/h3&gt;

&lt;p&gt;Let’s stay with our book store example. Now, the store wants to hand out cookbooks at a discount price before Christmas. We already follow the Single Responsibility Principle, so we create two separate classes: &lt;code&gt;CookbookDiscount&lt;/code&gt; to hold the details of the discount and &lt;code&gt;DiscountManager&lt;/code&gt; to apply the discount to the price.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CookbookDiscount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getCookbookDiscount&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"30% between Dec 1 and 24."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processCookbookDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CookbookDiscount&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code works fine until the store management informs us that their cookbook discount sales were so successful that they want to extend it. Now, they want to hand out every biography with a 50% discount on the subject’s birthday. To add the new feature, we create a new &lt;code&gt;BiographyDiscount&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BiographyDiscount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getBiographyDiscount&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"50% on the subject's birthday."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;     

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To process the new type of discount, we need to add the new functionality to the &lt;code&gt;DiscountManager&lt;/code&gt; class, too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processCookbookDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CookbookDiscount&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processBiographyDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BiographyDiscount&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, as we changed existing functionality, we violated the Open/Closed Principle. Although the above code works properly, it might add new vulnerabilities to the application. We don’t know how the new addition would interact with other parts of the code that depends on the &lt;code&gt;DiscountManager&lt;/code&gt; class. In a real-world application, this would mean that we need to test and deploy our entire app again.&lt;/p&gt;

&lt;p&gt;But, we can also choose to refactor our code by adding an extra layer of abstraction that represents all types of discounts. So, let’s create a new interface called &lt;code&gt;BookDiscount&lt;/code&gt; that the &lt;code&gt;CookbookDiscount&lt;/code&gt; and &lt;code&gt;BiographyDiscount&lt;/code&gt; classes will implement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;BookDiscount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getBookDiscount&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CookbookDiscount&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BookDiscount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getBookDiscount&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"30% between Dec 1 and 24."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BiographyDiscount&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BookDiscount&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getBookDiscount&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"50% on the subject's birthday."&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;DiscountManager&lt;/code&gt; can refer to the &lt;code&gt;BookDiscount&lt;/code&gt; interface instead of the concrete classes. When the &lt;code&gt;processBookDiscount()&lt;/code&gt; method is called, we can pass both &lt;code&gt;CookbookDiscount&lt;/code&gt; and &lt;code&gt;BiographyDiscount&lt;/code&gt; as an argument, as both are the implementation of the &lt;code&gt;BookDiscount&lt;/code&gt; interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DiscountManager&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processBookDiscount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BookDiscount&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The refactored code follows the Open/Closed principle, as we could add the new &lt;code&gt;CookbookDiscount&lt;/code&gt; class without modifying the existing code base. This also means that in the future, we can extend our app with other discount types (for instance, with &lt;code&gt;CrimebookDiscount&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The UML graph below shows how our example code looks like before and after the refactoring. On the left, you can see that &lt;code&gt;DiscountManager&lt;/code&gt; depends on the &lt;code&gt;CookbookDiscount&lt;/code&gt; and &lt;code&gt;BiographyDiscount&lt;/code&gt; classes. On the right, all three classes depend on the &lt;code&gt;BookDiscount&lt;/code&gt; abstract layer (&lt;code&gt;DiscountManager&lt;/code&gt; references it, while &lt;code&gt;CookbookDiscount&lt;/code&gt; and &lt;code&gt;BiographyDiscount&lt;/code&gt; implement it).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszzon7ds1257lz2z6dbu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fszzon7ds1257lz2z6dbu.jpg" alt="Open/Closed Principle" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Liskov Substitution Principle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oodesign.com/liskov-s-substitution-principle.html" rel="noopener noreferrer"&gt;Liskov Substitution Principle&lt;/a&gt; is the third principle of SOLID, represented by the letter “L”. It was &lt;a href="https://en.wikipedia.org/wiki/Barbara_Liskov" rel="noopener noreferrer"&gt;Barbara Liskov&lt;/a&gt; who introduced the principle in 1987 in her conference keynote talk “Data Abstraction”. The original phrasing of the Liskov Substitution Principle is a bit complicated, as it asserts that:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“In a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may substitute objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.).”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In layman’s terms, it states that an object of a superclass should be replaceable by objects of its subclasses without causing issues in the application. So, a child class should never change the characteristics of its parent class (such as the argument list and return types). You can implement the Liskov Substitution Principle by paying attention to the correct inheritance hierarchy.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example of the Liskov Substitution Principle
&lt;/h4&gt;

&lt;p&gt;Now, the book store asks us to add a new delivery functionality to the application. So, we create a &lt;code&gt;BookDelivery&lt;/code&gt; class that informs customers about the number of locations where they can collect their order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;titles&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getDeliveryLocations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the store also sells fancy hardcovers they only want to deliver to their high street shops. So, we create a new &lt;code&gt;HardcoverDelivery&lt;/code&gt; subclass that extends &lt;code&gt;BookDelivery&lt;/code&gt; and overrides the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method with its own functionality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HardcoverDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getDeliveryLocations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Later, the store asks us to create delivery functionalities for audiobooks, too. Now, we extend the existing &lt;code&gt;BookDelivery&lt;/code&gt; class with an &lt;code&gt;AudiobookDelivery&lt;/code&gt; subclass. But, when we want to override the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method, we realize that audiobooks can’t be delivered to physical locations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AudiobookDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getDeliveryLocations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* can't be implemented */&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could change some characteristics of the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method, however, that would violate the Liskov Substitution Principle. After the modification, we couldn’t replace the &lt;code&gt;BookDelivery&lt;/code&gt; superclass with the &lt;code&gt;AudiobookDelivery&lt;/code&gt; subclass without breaking the application.&lt;/p&gt;

&lt;p&gt;To solve the problem, we need to fix the inheritance hierarchy. Let’s introduce an extra layer that better differentiates book delivery types. The new &lt;code&gt;OfflineDelivery&lt;/code&gt; and &lt;code&gt;OnlineDelivery&lt;/code&gt; classes split up the &lt;code&gt;BookDelivery&lt;/code&gt; superclass. We also move the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method to &lt;code&gt;OfflineDelivery&lt;/code&gt; and create a new &lt;code&gt;getSoftwareOptions()&lt;/code&gt; method for the &lt;code&gt;OnlineDelivery&lt;/code&gt; class (as this is more suitable for online deliveries).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;userID&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OfflineDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getDeliveryLocations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OnlineDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getSoftwareOptions&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the refactored code, &lt;code&gt;HardcoverDelivery&lt;/code&gt; will be the child class of &lt;code&gt;OfflineDelivery&lt;/code&gt; and it will override the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method with its own functionality.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AudiobookDelivery&lt;/code&gt; will be the child class of &lt;code&gt;OnlineDelivery&lt;/code&gt; which is good news, as now it doesn’t have to deal with the &lt;code&gt;getDeliveryLocations()&lt;/code&gt; method. Instead, it can override the &lt;code&gt;getSoftwareOptions()&lt;/code&gt; method of its parent with its own implementation (for instance, by listing and embedding available audio players).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HardcoverDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;OfflineDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getDeliveryLocations&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AudiobookDelivery&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;OnlineDelivery&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getSoftwareOptions&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the refactoring, we could use any subclass in place of its superclass without breaking the application.&lt;/p&gt;

&lt;p&gt;On the UML graph below, you can see that by applying the Liskov Substitution Principle, we added an extra layer to the inheritance hierarchy. While the new architecture is more complex, it provides us with a more flexible design.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wu2je4uw9c86edc3ptn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4wu2je4uw9c86edc3ptn.jpg" alt="Liskov Substitution Principle" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interface Segregation Principle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oodesign.com/interface-segregation-principle.html" rel="noopener noreferrer"&gt;Interface Segregation Principle&lt;/a&gt; is the fourth SOLID design principle represented by the letter “I” in the acronym. It was Robert C Martin who first defined the principle by stating that “clients should not be forced to depend on methods they don’t use.” By clients, he means classes that implement interfaces. In other words, interfaces shouldn’t include too many functionalities.&lt;/p&gt;

&lt;p&gt;The violation of Interface Segregation Principle harms code readability and forces programmers to write dummy methods that do nothing. In a well-designed application, you should avoid interface pollution (also called fat interfaces). The solution is to create smaller interfaces that you can implement more flexibly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of the Interface Segregation Principle
&lt;/h3&gt;

&lt;p&gt;Let’s add some user actions to our online bookstore so that customers can interact with the content before making a purchase. To do so, we create an interface called &lt;code&gt;BookAction&lt;/code&gt; with three methods: &lt;code&gt;seeReviews()&lt;/code&gt;, &lt;code&gt;searchSecondHand()&lt;/code&gt;, and &lt;code&gt;listenSample()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchSecondhand&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;listenSample&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we create two classes: &lt;code&gt;HardcoverUI&lt;/code&gt; and an &lt;code&gt;AudiobookUI&lt;/code&gt; that implement the &lt;code&gt;BookAction&lt;/code&gt; interface with their own functionalities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HardcoverUI&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchSecondhand&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;listenSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AudiobookUI&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchSecondhand&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;listenSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both classes depend on methods they don’t use, so we have broken the Interface Segregation Principle. Hardcover books can’t be listened to, so the &lt;code&gt;HardcoverUI&lt;/code&gt; class doesn’t need the &lt;code&gt;listenSample()&lt;/code&gt; method. Similarly, audiobooks don’t have second-hand copies, so the &lt;code&gt;AudiobookUI&lt;/code&gt; class doesn’t need it, either.&lt;/p&gt;

&lt;p&gt;However, as the &lt;code&gt;BookAction&lt;/code&gt; interface include these methods, all of its dependent classes have to implement them. In other words, &lt;code&gt;BookAction&lt;/code&gt; is a polluted interface that we need to segregate. Let’s extend it with two more specific sub-interfaces: &lt;code&gt;HardcoverAction&lt;/code&gt; and &lt;code&gt;AudioAction&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;HardcoverAction&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchSecondhand&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;AudioAction&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BookAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;listenSample&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the &lt;code&gt;HardcoverUI&lt;/code&gt; class can implement the &lt;code&gt;HardcoverAction&lt;/code&gt; interface and the &lt;code&gt;AudiobookUI&lt;/code&gt; class can implement the &lt;code&gt;AudioAction&lt;/code&gt; interface.&lt;/p&gt;

&lt;p&gt;This way, both classes can implement the &lt;code&gt;seeReviews()&lt;/code&gt; method of the &lt;code&gt;BookAction&lt;/code&gt; super-interface. However, &lt;code&gt;HardcoverUI&lt;/code&gt; doesn’t have to implement the irrelevant &lt;code&gt;listenSample()&lt;/code&gt; method and &lt;code&gt;AudioUI&lt;/code&gt; doesn’t have to implement &lt;code&gt;searchSecondhand()&lt;/code&gt;, either.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HardcoverUI&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;HardcoverAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;searchSecondhand&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AudiobookUI&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;AudioAction&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;listenSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The refactored code follows the Interface Segregation Principle, as neither classes depend on methods they don’t use. The UML diagram below excellently shows that the segregated interfaces lead to simpler classes that only implement the methods they really need:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97eklfdu68j7cedv7jn6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F97eklfdu68j7cedv7jn6.jpg" alt="Interface Segregation Principle" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependency Inversion Principle
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.oodesign.com/dependency-inversion-principle.html" rel="noopener noreferrer"&gt;Dependency Inversion Principle&lt;/a&gt; is the fifth SOLID design principle represented by the last “D” and introduced by Robert C Martin. The goal of the Dependency Inversion Principle is to avoid tightly coupled code, as it easily breaks the application. The principle states that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“High-level modules should not depend on low-level modules. Both should depend on abstractions.”&lt;/p&gt;

&lt;p&gt;“Abstractions should not depend on details. Details should depend on abstractions.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, you need to decouple high-level and low-level classes. High-level classes usually encapsulate complex logic while low-level classes include data or utilities. Typically, most people would want to make high-level classes depend on low-level classes. However, according to the Dependency Inversion Principle, you need to invert the dependency. Otherwise, when the low-level class is replaced, the high-level class will be affected, too.&lt;/p&gt;

&lt;p&gt;As a solution, you need to create an abstract layer for low-level classes, so that high-level classes can depend on abstraction rather than concrete implementations.&lt;/p&gt;

&lt;p&gt;Robert C Martin also mentions that the Dependency Inversion Principle is a specific combination of the Open/Closed and Liskov Substitution Principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example of the Dependency Inversion Principle
&lt;/h3&gt;

&lt;p&gt;Now, the book store asked us to build a new feature that enables customers to put their favorite books on a shelf.&lt;/p&gt;

&lt;p&gt;To implement the new functionality, we create a lower-level &lt;code&gt;Book&lt;/code&gt; class and a higher-level &lt;code&gt;Shelf&lt;/code&gt; class. The &lt;code&gt;Book&lt;/code&gt; class will allow users to see reviews and read a sample of each book they store on their shelves. The &lt;code&gt;Shelf&lt;/code&gt; class will let them add a book to their shelf and customize the shelf.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;readSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shelf&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addBook&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;customizeShelf&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything looks fine, but as the high-level &lt;code&gt;Shelf&lt;/code&gt; class depends on the low-level &lt;code&gt;Book&lt;/code&gt;, the above code violates the Dependency Inversion Principle. This becomes clear when the store asks us to enable customers to add DVDs to their shelves, too. To fulfill the demand, we create a new &lt;code&gt;DVD&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DVD&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;watchSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we should modify the &lt;code&gt;Shelf&lt;/code&gt; class so that it can accept DVDs, too. However, this would clearly break the Open/Closed Principle.&lt;br&gt;
The solution is to create an abstraction layer for the lower-level classes (&lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;DVD&lt;/code&gt;). We’ll do so by introducing the &lt;code&gt;Product&lt;/code&gt; interface that both classes will implement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getSample&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DVD&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;seeReviews&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;getSample&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;Shelf&lt;/code&gt; can reference the &lt;code&gt;Product&lt;/code&gt; interface instead of its implementations (&lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;DVD&lt;/code&gt;). The refactored code also allows us to later introduce new product types (for instance, &lt;code&gt;Magazine&lt;/code&gt;) that customers can put on their shelves, too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shelf&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addProduct&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;customizeShelf&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{...}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code also follows the Liskov Substitution Principle, as the &lt;code&gt;Product&lt;/code&gt; type can be substituted with both of its subtypes (&lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;DVD&lt;/code&gt;) without breaking the program. At the same time, we have also implemented the Dependency Inversion Principle, as in the refactored code, high-level classes don’t depend on low-level classes, either.&lt;/p&gt;

&lt;p&gt;As you can see on the left of the UML graph below, the high-level &lt;code&gt;Shelf&lt;/code&gt; class depends on the low-level &lt;code&gt;Book&lt;/code&gt; before the refactoring. Without applying the Dependency Inversion Principle, we should make it depend on the low-level &lt;code&gt;DVD&lt;/code&gt; class, too. However, after the refactoring, both the high-level and low-level classes depend on the abstract &lt;code&gt;Product&lt;/code&gt; interface (&lt;code&gt;Shelf&lt;/code&gt; refers to it, while &lt;code&gt;Book&lt;/code&gt; and &lt;code&gt;DVD&lt;/code&gt; implement it).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd2ytg11iv97gphubua4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwd2ytg11iv97gphubua4.jpg" alt="Dependency Inversion Principle" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How should you implement SOLID design principles?
&lt;/h2&gt;

&lt;p&gt;Implementing the SOLID design principles increases the overall complexity of a code base, but it leads to more flexible design. Besides monolithic apps, you can also apply SOLID design principles to &lt;a href="https://raygun.com/blog/what-are-microservices/" rel="noopener noreferrer"&gt;microservices&lt;/a&gt; where you can treat each microservice as a standalone code module (like a class in the above examples).&lt;/p&gt;

&lt;p&gt;When you break a SOLID design principle, Java and other compiled languages might throw an &lt;a href="https://raygun.com/blog/java-exceptions-terminology/" rel="noopener noreferrer"&gt;Exception&lt;/a&gt;, but it doesn’t always happen. Software architecture problems are hard to detect, but advanced diagnostic software such as &lt;a href="https://raygun.com/platform/apm" rel="noopener noreferrer"&gt;APM tools&lt;/a&gt; can provide you with many useful hints.&lt;/p&gt;

</description>
      <category>java</category>
      <category>beginners</category>
      <category>designpatterns</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
