<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ solid - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ solid - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 17:40:15 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/solid/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What are the SOLID Principles in Java? Explained With Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ In this article, you'll learn about the SOLID principles. You'll gain an understanding of each principle along with Java code examples. SOLID principles are a set of five design principles used in object-oriented programming. Adhering to these princi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/introduction-to-solid-principles/</link>
                <guid isPermaLink="false">66ba1abe4067550ef7868690</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Anjan Baradwaj ]]>
                </dc:creator>
                <pubDate>Mon, 24 Jun 2024 15:45:17 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/06/kozjat-mlsSgJ6LiP4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, you'll learn about the SOLID principles. You'll gain an understanding of each principle along with Java code examples.</p>
<p>SOLID principles are a set of five design principles used in object-oriented programming. Adhering to these principles will help you develop robust software. They will make your code more efficient, readable, and maintainable.</p>
<p>SOLID is an acronym that stands for:</p>
<ul>
<li>Single Responsibility Principle</li>
<li>Open/Closed Principle</li>
<li>Liskov Substitution Principle</li>
<li>Interface Segregation Principle</li>
<li>Dependency Inversion Principle</li>
</ul>
<h2 id="heading-single-responsibility-principle">Single Responsibility Principle</h2>
<p>The single responsibilty principle states that every class must have a single, focused responsibility, a single reason to change.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span></span>{
  <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getDesignation</span><span class="hljs-params">(<span class="hljs-keyword">int</span> employeeID)</span></span>{ <span class="hljs-comment">// }</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">updateSalary</span><span class="hljs-params">(<span class="hljs-keyword">int</span> employeeID)</span></span>{ <span class="hljs-comment">// }</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendMail</span><span class="hljs-params">()</span></span>{ <span class="hljs-comment">// }</span>
}
</code></pre>
<p>In the above example, the <code>Employee</code> class has a few employee class-specific behaviors like <code>getDesignation</code> &amp; <code>updateSalary</code>. </p>
<p>Additionally, it also has another method named <code>sendMail</code> which deviates from the responsibility of the <code>Employee</code> class. </p>
<p>This behavior is not specific to this class, and having it violates the single responsibility principle. To overcome this, you can move the <code>sendMail</code> method to a separate class.</p>
<p>Here's how:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span></span>{
  <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getDesignation</span><span class="hljs-params">(<span class="hljs-keyword">int</span> employeeID)</span></span>{ <span class="hljs-comment">// }</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">updateSalary</span><span class="hljs-params">(<span class="hljs-keyword">int</span> employeeID)</span></span>{ <span class="hljs-comment">// }</span>
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NotificationService</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendMail</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// }</span>
}
</code></pre>
<h2 id="heading-openclosed-principle">Open/Closed Principle</h2>
<p>According to the open/closed priniciple, components must be open for extension, but, closed for modification. To understand this principle, let us take an example of a class that calculates the area of a shape.</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">AreaCalculator</span><span class="hljs-params">()</span></span>{
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">area</span><span class="hljs-params">(Shape shape)</span></span>{
    <span class="hljs-keyword">double</span> areaOfShape;
    <span class="hljs-keyword">if</span>(shape <span class="hljs-keyword">instanceof</span> Square){
        <span class="hljs-comment">// calculate the area of Square</span>
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(shape <span class="hljs-keyword">instanceof</span> Circle){
        <span class="hljs-comment">// calculate the area of Circle</span>
    }
    <span class="hljs-keyword">return</span> areaOfShape;
  }
</code></pre>
<p>The problem with the above example is that if there is a new instance of type <code>Shape</code> for which you need to calculate the area in the future, you have to modify the above class by adding another conditional <code>else-if</code> block. You will end up doing this for every new object of the <code>Shape</code> type.</p>
<p>To overcome this, you can create an interface and have each <code>Shape</code> implement this interface. Then, each class can provide its own implementation for calculating the area. This will make your program easily extensible in the future. </p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IAreaCalculator</span>()</span>{
  <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">area</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IAreaCalculator</span></span>{
  <span class="hljs-meta">@Override</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">area</span><span class="hljs-params">()</span></span>{
    System.out.println(<span class="hljs-string">"Calculating area for Square"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0.0</span>;
   }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Circle</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IAreaCalculator</span></span>{
  <span class="hljs-meta">@Override</span>
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">area</span><span class="hljs-params">()</span></span>{
    System.out.println(<span class="hljs-string">"Calculating area for Circle"</span>);
    <span class="hljs-keyword">return</span> <span class="hljs-number">0.0</span>;
   }
}
</code></pre>
<h2 id="heading-liskov-substitution-principle">Liskov Substitution Principle</h2>
<p>The Liskov substitution principle states that you must be able to replace a superclass object with a subclass object without affecting the correctness of the program.</p>
<pre><code class="lang-java"><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span></span>{
   <span class="hljs-function"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Eagle</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Bird</span> </span>{
   <span class="hljs-meta">@Override</span>
   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// some implementation }</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Ostrich</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Bird</span> </span>{
   <span class="hljs-meta">@Override</span>
   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// dummy implementation }</span>
}
</code></pre>
<p>In the above example, the <code>Eagle</code> class and the <code>Ostrich</code> class both extend the <code>Bird</code> class and override the <code>fly()</code> method. However, the <code>Ostrich</code> class is forced to provide a dummy implementation because it cannot fly, and therefore it does not behave the same way if we replace the <code>Bird</code> class object with it. </p>
<p>This violates the Liskov substitution principle. To address this, we can create a separate class for birds that can fly and have the <code>Eagle</code> extend it, while other birds can extend a different class, which will not include any <code>fly</code> behavior.</p>
<pre><code class="lang-java"><span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FlyingBird</span></span>{
   <span class="hljs-function"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-keyword">abstract</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">NonFlyingBird</span></span>{
   <span class="hljs-function"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doSomething</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Eagle</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">FlyingBird</span> </span>{
   <span class="hljs-meta">@Override</span>
   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// some implementation }</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Ostrich</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">NonFlyingBird</span> </span>{
   <span class="hljs-meta">@Override</span>
   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">doSomething</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// some implementation }</span>
}
</code></pre>
<h2 id="heading-interface-segregation-principle">Interface Segregation Principle</h2>
<p>According to the interface segregation principle, you should build small, focused interfaces that do not force the client to implement behavior they do not need.</p>
<p>A straightforward example would be to have an interface that calculates both the area and volume of a shape.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IShapeAreaCalculator</span>()</span>{
  <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateArea</span><span class="hljs-params">()</span></span>;
  <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateVolume</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IShapeAreaCalculator</span></span>{
  <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateArea</span><span class="hljs-params">()</span></span>{ <span class="hljs-comment">// calculate the area }</span>
  <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateVolume</span><span class="hljs-params">()</span></span>{ <span class="hljs-comment">// dummy implementation }</span>
}
</code></pre>
<p>The issue with this is that if a <code>Square</code> shape implements this, then it is forced to implement the <code>calculateVolume()</code> method, which it does not need. </p>
<p>On the other hand, a <code>Cube</code> can implement both. To overcome this, we can segregate the interface and have two separate interfaces: one for calculating the area and another for calculating the volume. This will allow individual shapes to decide what to implement.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IAreaCalculator</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateArea</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">IVolumeCalculator</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">double</span> <span class="hljs-title">calculateVolume</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IAreaCalculator</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">calculateArea</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// calculate the area }</span>
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cube</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">IAreaCalculator</span>, <span class="hljs-title">IVolumeCalculator</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">calculateArea</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// calculate the area }</span>

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">calculateVolume</span><span class="hljs-params">()</span> </span>{<span class="hljs-comment">// calculate the volume }</span>
}
</code></pre>
<h2 id="heading-dependency-inversion-principle">Dependency Inversion Principle</h2>
<p>In the dependency inversion principle, high-level modules should not depend on low-level modules. In other words, you must follow abstraction and ensure loose coupling</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Notification</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmailNotification</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notification</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Sending notification via email"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span> </span>{
    <span class="hljs-keyword">private</span> EmailNotification emailNotification; 
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Employee</span><span class="hljs-params">(EmailNotification emailNotification)</span> </span>{
        <span class="hljs-keyword">this</span>.emailNotification = emailNotification;
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notifyUser</span><span class="hljs-params">()</span> </span>{
        emailNotification.notify();
    }
}
</code></pre>
<p>In the given example, the <code>Employee</code> class depends directly on the <code>EmailNotification</code> class, which is a low-level module. This violates the  dependency inversion principle.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Notification</span></span>{
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Employee</span></span>{
  <span class="hljs-keyword">private</span> Notification notification;
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Employee</span><span class="hljs-params">(Notification notification)</span></span>{
      <span class="hljs-keyword">this</span>.notification = notification;
  }
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notifyUser</span><span class="hljs-params">()</span></span>{
    notification.notify();
  }
 }

 <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">EmailNotification</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notification</span></span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">notify</span><span class="hljs-params">()</span></span>{
        <span class="hljs-comment">//implement notification via email </span>
    }
 }

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String [] args)</span></span>{
    Notification notification = <span class="hljs-keyword">new</span> EmailNotification();
    Employee employee = <span class="hljs-keyword">new</span> Employee(notification);
    employee.notifyUser();
 }
</code></pre>
<p>In the above example, we have ensured loose coupling. <code>Employee</code> is not dependent on any concrete implementation, rather, it depends only on the abstraction (notification interface). </p>
<p>If we need to change the notification mode, we can create a new implementation and pass it to the <code>Employee</code>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In conclusion, we've covered the essence of SOLID principles through straightforward examples in this article. </p>
<p>These principles form the building blocks for developing applications that are highly extensible and reusable.</p>
<p>Let's connect on <a target="_blank" href="https://www.linkedin.com/in/abaradwaj/">LinkedIn</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Resilient Microservice Systems – SOLID Principles for Microservices ]]>
                </title>
                <description>
                    <![CDATA[ We are in the era of transformative technology with several innovations springing up to improve service delivery and enhance customers’ satisfaction. More so is the introduction of microservices and other distributed systems into the software industr... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-for-microservices/</link>
                <guid isPermaLink="false">66bb58d40da5b03e481107da</guid>
                
                    <category>
                        <![CDATA[ Microservices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwatobi ]]>
                </dc:creator>
                <pubDate>Tue, 21 May 2024 09:56:55 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/solid.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>We are in the era of transformative technology with several innovations springing up to improve service delivery and enhance customers’ satisfaction. More so is the introduction of microservices and other distributed systems into the software industry to revolutionize enterprise application development.</p>
<p>Its introduction has helped to solve problems associated with the age-long monolithic software development approach, overcoming its cons and achieving scalability.</p>
<p>In this article, I hope to dive deep into what microservices entail and highlight its significant use cases. Also, I will dive deep into the SOLID principles and other best practices necessary to build efficient microservices. With that, let's get started.</p>
<p>First of all, what is a microservice?</p>
<h2 id="heading-what-is-a-microservice">What is a Microservice?</h2>
<p>This is a type of system architecture in which an application gets structured as a confluence of several independent, loosely coupled independent services. This ensures that each aspect of the overall application gets managed individually and still functions irrespective of the current state of other independent services. These independent servers still allow for information sharing over a given network.</p>
<p>It actively mirrors the distributed system model which segregates the various computers on a network and shares resources amongst them. The adoption of this model by big enterprises has been seen to be advantageous as it has greatly reduced server downtime, minimized costs and maintained efficiency.</p>
<p>The microservice system architecture also provides an upper hand to these firms as it rapidly provides scaling opportunities in case of a spike in user visits. The scaling could either be horizontal which involves activating multiple servers to handle user requests or vertical which involves increasing the CPU power of the server to efficiently handle user requests.</p>
<p>Unlike conventional monolithic systems, microservice best practices deviate slightly from the conventional ACID principles designed for related databases. Hence it's important to learn about best practices and principles which serve as a basis for building resilient microservices. </p>
<p>This will take us into the world of the SOLID principles.  The solid principles form the general basis of object-oriented programming and design but have been adapted in the context of building resilient microservices.  But what does SOLID represent?</p>
<ul>
<li>Single Responsibility Principle</li>
<li>Open-Close Principle</li>
<li>Liskov Substitution Principle</li>
<li>Interface Segregation Principle</li>
<li>Dependency Inversion Principle</li>
</ul>
<p>Let's discuss these in detail.</p>
<h2 id="heading-single-responsibility-principle">Single Responsibility Principle</h2>
<p>This principle states that each service in the grand microservice architecture is responsible for a single functionality or possesses a single reason to change. This implies that the service in question is solely and wholly built to fulfil a specific application functionality and it is done cohesively. </p>
<p>This feature provides it with the liberty to scale bigger to effectively deliver on that given functionality. This forms the baseline for microservices development as it reduces the interference of several services due to service interdependency which is a side effect of monolithic applications.</p>
<h2 id="heading-open-close-principle">Open-Close Principle</h2>
<p>This principle was initially applied for object-oriented programming but is now also adapted for microservices development. It entails that services created within the overall microservice architecture are open to extension with additional service functionalities and communication via the services interface but should be closed to code modification. </p>
<p>This principle is necessary as code modification affects service functionality and stability and also serves as a risk for introducing bugs to the existing code which can ultimately cause errors in system function.</p>
<p>To ensure this, features such as code versioning allow for newer versions of an existing service to be created and deployed without affecting the older versions' functionality and maintain the system's efficiency. Also ensuring the implementation of APIs on each service and the concept of dependency inversion (which will be discussed in the subsequent section) helps to achieve this principle.</p>
<h2 id="heading-liskov-substitution-principle">Liskov Substitution Principle</h2>
<p>This principle is named after its originator, Barbara Liskov. It means that services built within complex microservice architecture can and should be easily substituted or replaced with no or minimal side effects to the entire microservice architecture. This feature also enables developers to build modular microservices applications.</p>
<p>It also enables the execution of the dependency inversion principle which will be discussed in subsequent paragraphs. Achieving this principle involves structuring the microservice architecture with the use of interfaces and classes which allows for the reuse and light coupling of services.</p>
<h2 id="heading-interface-segregation-principle-isp">Interface Segregation Principle (ISP)</h2>
<p>This principle builds on the Liskov substitution principle and it simply advocates for ensuring that interfaces used for each service are specific for the users who interact with them solely. This ensures that the interface delivers the specific function intended by the service created. This would in turn minimize service interdependency among various services and ensure service application autonomy, enabling it to achieve the desired scalability and overall efficiency possible.</p>
<p>This, alongside the Liskov substitution principle, allows for seamless microservice application evolution over a given cycle. To achieve this, it is important to ensure a minimal reliance of the service on external dependencies and also declare explicit and distinct functions for each service.</p>
<h2 id="heading-dependency-inversion-principle">Dependency Inversion Principle</h2>
<p>This principle negates the age-long tradition in which high-level modules and services tend to depend on smaller low-level services to achieve the necessary efficiency and correctly perform their designated function. It now implies that the high-level services/modules should not depend on anything from the low-level services and both should only interact based on the existing abstraction. In our case, this implies that the interfaces already discussed earlier.</p>
<p>This principle, in line with the other principles, permits easy scaling of each service or module in question and also allows for service reuse or substitution whenever such is needed. This principle has also revolutionized the way applications get built as they now delineate the functions and autonomy of each service in the application.</p>
<h2 id="heading-additional-information">Additional Information</h2>
<p>So far, we have shed light on the SOLID microservices design principles. However, other additional tips which could be of great help when building microservices include:</p>
<h3 id="heading-availability-over-consistency-principle">Availability Over Consistency Principle</h3>
<p>This principle is based on the CAP theorem (consistency, availability and partition tolerance. Hypothetically, a system should have all these components implemented and fully functional but in reality, this isn’t so. Ensuring these works often results in network lags, which affects system efficiency, resulting in the need for tradeoffs among these components.</p>
<p>In the case of microservices development, the need for a service to be continually consistent in providing an updated response to a request gets overridden by the need for the service to be available with minimal downtime. Eventually, the overall microservice consistency is achieved during a given period via conflict resolution techniques and other consensus protocols.</p>
<h3 id="heading-easy-deployability-principle">Easy Deployability Principle</h3>
<p>Unlike conventional monolithic applications, deploying microservices is a bit complex as it requires ensuring seamless communication across various deployments. However, this can be achieved by mastery of some techniques.</p>
<p>Firstly, it's important to possess knowledge of containerization and containerization tools such as Docker. Additionally, knowledge of orchestration tools like Kubernetes is an additional advantage. Adequate knowledge of Infrastructure as Code tools such as Terraform also helps as it gives the developers great control over the application and allows for easy versioning. Provision of monitoring and observability tools to help detect any anomaly in the operations.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With this, we have come to the end of the tutorial. We hope you’ve learned essentially about the principles and other best practices to have in mind when building microservices and other distributed applications.</p>
<p>Feel free to drop comments and questions in the box below, and also check out my other articles <a target="_blank" href="https://linktr.ee/tobilyn77">here</a>. Till next time, keep on coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is SOLID? Principles for Better Software Design ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID principles are a set of guidelines for writing high-quality, maintainable, and scalable software.  They were introduced by Robert C. Martin in his 2000 paper “Design Principles and Design Patterns” to help developers write software that is ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-for-better-software-design/</link>
                <guid isPermaLink="false">66ba0ec7439ed06e055759f0</guid>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Krishna ]]>
                </dc:creator>
                <pubDate>Wed, 03 May 2023 14:00:01 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/04/solid-principles.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The SOLID principles are a set of guidelines for writing high-quality, maintainable, and scalable software. </p>
<p>They were introduced by Robert C. Martin in his 2000 paper <a target="_blank" href="https://fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf">“Design Principles and Design Patterns”</a> to help developers write software that is easy to understand, modify, and extend. </p>
<p>These concepts were later built upon by Michael Feathers, who introduced us to the SOLID acronym.</p>
<p>The SOLID acronym stands for:</p>
<ul>
<li><strong>S</strong>ingle Responsibility Principle (SRP)</li>
<li><strong>O</strong>pen-Closed Principle (OCP)</li>
<li><strong>L</strong>iskov Substitution Principle (LSP)</li>
<li><strong>I</strong>nterface Segregation Principle (ISP)</li>
<li><strong>D</strong>ependency Inversion Principle (DIP)</li>
</ul>
<p>These principles provide a way for developers to organize their code and create software that is flexible, easy to change, and testable. Applying SOLID principles can lead to code that is more modular, maintainable, and extensible, and it can make it easier for developers to work collaboratively on a codebase.</p>
<p>In this tutorial, we will explore each of the SOLID principles in detail, explain why they are important, and provide examples of how you can apply them in practice. By the end of this tutorial, you should have a good understanding of the SOLID principles and how to apply them to your software development projects.</p>
<h2 id="heading-what-is-the-single-responsibility-principle"><strong>What is the Single Responsibility Principle?</strong></h2>
<p>The Single Responsibility Principle (SRP) states that <strong>a class should have only one reason to change</strong>, or in other words, <strong>it should have only one responsibility</strong>. This means that a class should have only one job to do, and it should do it well.</p>
<p>If a class has too many responsibilities, it can become hard to understand, maintain, and modify. Changes to one responsibility can inadvertently affect another responsibility, leading to unintended consequences and bugs. By following SRP, we can create code that is more modular, easier to understand, and less prone to errors.</p>
<p>Let's take an example that violates the SRP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Marker</span> </span>{
    String name;
    String color;
    <span class="hljs-keyword">int</span> price;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Marker</span><span class="hljs-params">(String name, String color, <span class="hljs-keyword">int</span> price)</span> </span>{
        <span class="hljs-keyword">this</span>.name = name;
        <span class="hljs-keyword">this</span>.color = color;
        <span class="hljs-keyword">this</span>.price = price;
    }
}
</code></pre>
<p>The above code defines a simple <code>Marker</code> class having three instance variables – <code>name</code>, <code>color</code> and <code>price</code>.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Invoice</span> </span>{
    <span class="hljs-keyword">private</span> Marker marker;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> quantity;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Invoice</span><span class="hljs-params">(Marker marker, <span class="hljs-keyword">int</span> quantity)</span> </span>{
        <span class="hljs-keyword">this</span>.marker = marker;
        <span class="hljs-keyword">this</span>.quantity = quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">calculateTotal</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> marker.price * <span class="hljs-keyword">this</span>.quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInvoice</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// printing implementation</span>
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<p>The above <code>Invoice</code> class violates the SRP because it has multiple responsibilities – it is responsible for calculating the total amount, printing the invoice, and saving the invoice to the database. As a result, if the calculation logic changes, such as the addition of taxes, the <code>calculateTotal()</code> method would require modification. Similarly, if the printing or database-saving implementation changes at any point, the class would need to be changed. </p>
<p>There are several reasons for the class to be modified, which could lead to increased maintenance costs and complexity.</p>
<p>Here's how you can modify the code to follow the SRP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Invoice</span> </span>{
    <span class="hljs-keyword">private</span> Marker marker;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> quantity;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Invoice</span><span class="hljs-params">(Marker marker, <span class="hljs-keyword">int</span> quantity)</span> </span>{
        <span class="hljs-keyword">this</span>.marker = marker;
        <span class="hljs-keyword">this</span>.quantity = quantity;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">calculateTotal</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> marker.price * <span class="hljs-keyword">this</span>.quantity;
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoiceDao</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoicePrinter</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoicePrinter</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">printInvoice</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// printing implementation</span>
    }
}
</code></pre>
<p>In this refactored example, we have split the responsibilities of the <code>Invoice</code> class into three separate classes: <code>Invoice</code>, <code>InvoiceDao</code>, and <code>InvoicePrinter</code>. </p>
<p>The <code>Invoice</code> class is responsible only for calculating the total amount, and the printing and saving responsibilities have been delegated to separate classes. This makes the code more modular, easier to understand, and less prone to errors.</p>
<h2 id="heading-what-is-the-open-closed-principle"><strong>What is the Open-Closed Principle?</strong></h2>
<p>The Open-Closed Principle (OCP) states that <strong>software entities (classes, modules, functions, and so on) should be open for extension but closed for modification</strong>. This means that the behavior of a software entity can be extended without modifying its source code.</p>
<p>The OCP is essential because it promotes software extensibility and maintainability. By allowing software entities to be extended without modification, developers can add new functionality without the risk of breaking existing code. This results in code that is easier to maintain, extend, and reuse.</p>
<p>Let's take the previous example again.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-keyword">private</span> Invoice invoice;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">InvoiceDao</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-keyword">this</span>.invoice = invoice;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">saveToDb</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}
</code></pre>
<p>The <code>InvoiceDao</code> class has a single responsibility of saving the invoice to the database. But, suppose there's a new requirement to save the invoice to a file as well. One way to implement this requirement would be to modify the existing <code>InvoiceDao</code> class by adding a <code>saveToFile()</code> method. But this violates the Open-Closed Principle because it modifies the existing code that has already been tested and is live in production.</p>
<p>To follow the OCP, a better solution would be to create an <code>InvoiceDao</code> interface and implement it separately for database and file saving as shown below:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DatabaseInvoiceDao</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-comment">// save to database implementation</span>
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FileInvoiceDao</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">InvoiceDao</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">save</span><span class="hljs-params">(Invoice invoice)</span> </span>{
        <span class="hljs-comment">// save to file implementation</span>
    }
}
</code></pre>
<p>This way, if there's a new requirement to save the invoice to another data store, you can implement a new <code>InvoiceDao</code> implementation without modifying the existing code. Now the <code>InvoiceDao</code> interface is open for extension and closed for modification, which follows the OCP.</p>
<h2 id="heading-what-is-the-liskov-substitution-principle"><strong>What is the </strong>L<strong>iskov Substitution Principle?</strong></h2>
<p>The Liskov Substitution Principle (LSP) states that <strong>any instance of a derived class should be substitutable for an instance of its base class without affecting the correctness of the program</strong>. </p>
<p>In other words, a derived class should behave like its base class in all contexts. In more simple terms, if class A is a subtype of class B, you should be able to replace B with A without breaking the behavior of your program.</p>
<p>The importance of the LSP lies in its ability to ensure that the behavior of a program remains consistent and predictable when substituting objects of different classes. Violating the LSP can lead to unexpected behavior, bugs, and maintainability issues.</p>
<p>Let's take an example.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Bike</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>In the given example, the interface <code>Bike</code> has two methods, <code>turnOnEngine()</code> and <code>accelerate()</code>. Two classes implement this interface, <code>Motorbike</code> and <code>Bicycle</code>.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Motorbike</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Bike</span> </span>{

    <span class="hljs-keyword">boolean</span> isEngineOn;
    <span class="hljs-keyword">int</span> speed;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span> </span>{
        isEngineOn = <span class="hljs-keyword">true</span>;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span> </span>{
        speed += <span class="hljs-number">5</span>;
    }
}
</code></pre>
<p><code>Motorbike</code> correctly implements the <code>turnOnEngine()</code> method, as it sets the <code>isEngineOn</code> boolean to true. It also correctly implements the <code>accelerate()</code> method by increasing the <code>speed</code> by 5.</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bicycle</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Bike</span> </span>{

    <span class="hljs-keyword">boolean</span> isEngineOn;
    <span class="hljs-keyword">int</span> speed;

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">turnOnEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> AssertionError(<span class="hljs-string">"There is no engine!"</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">accelerate</span><span class="hljs-params">()</span> </span>{
        speed += <span class="hljs-number">5</span>;
    }
}
</code></pre>
<p>However, the <code>Bicycle</code> class throws an <code>AssertionError</code> in the <code>turnOnEngine()</code> method because it has no engine. This means that an instance of <code>Bicycle</code> cannot be substituted for an instance of <code>Bike</code> without breaking the behavior of the program.</p>
<p>In other words, if the <code>Bicycle</code> class is considered a subtype of the <code>Bike</code> interface, then according to the LSP, any instance of <code>Bike</code> should be replaceable with an instance of <code>Bicycle</code> without altering the correctness of the program. </p>
<p>But in this case, it's not true because <code>Bicycle</code> throws an <code>AssertionError</code> while trying to turn on the engine. Therefore, the code violates the LSP.</p>
<h2 id="heading-what-is-the-interface-segregation-principle"><strong>What is the </strong>I<strong>nterface Segregation Principle?</strong></h2>
<p>The Interface Segregation Principle (ISP) focuses on designing interfaces that are specific to their client's needs. It states that no client should be forced to depend on methods it does not use.</p>
<p>The principle suggests that <strong>instead of creating a large interface that covers all the possible methods, it's better to create smaller, more focused interfaces for specific use cases</strong>. This approach results in interfaces that are more cohesive and less coupled.</p>
<p>Consider a <code>Vehicle</code> interface as below:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Vehicle</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>And then you have a class called <code>Car</code> that implements the <code>Vehicle</code> interface:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Vehicle</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnsupportedOperationException(<span class="hljs-string">"This vehicle cannot fly."</span>);
    }
}
</code></pre>
<p>In this example, the <code>Vehicle</code> interface has too many methods. The <code>Car</code> class is forced to implement all of them, even though they cannot fly. This violates the ISP because the <code>Vehicle</code> interface is not properly segregated into smaller interfaces based on related functionality.</p>
<p>Let's understand how you can follow the ISP here. Suppose you refactor the <code>Vehicle</code> interface into smaller, more focused interfaces:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Drivable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Flyable</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>Now, you can have a class called <code>Car</code> that only implements the <code>Drivable</code> interface:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Car</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Drivable</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }
}
</code></pre>
<p>And, thanks to interface segregation, you can have another class called <code>Airplane</code> that implements both the <code>Drivable</code> and <code>Flyable</code> interfaces:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Airplane</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Drivable</span>, <span class="hljs-title">Flyable</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">startEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">stopEngine</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">drive</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">fly</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// implementation</span>
    }
}
</code></pre>
<p>In this example, you have properly segregated the <code>Vehicle</code> interface into smaller interfaces based on related functionality. This adheres to the ISP and makes your code more flexible and maintainable.</p>
<h2 id="heading-what-is-the-dependency-inversion-principle"><strong>What is the Dependency Inversion Principle?</strong></h2>
<p>The Dependency Inversion Principle (DIP) states that <strong>high-level modules should not depend on low-level modules, but both should depend on abstractions</strong>. Abstractions should not depend on details – details should depend on abstractions. </p>
<p>This principle aims to reduce coupling between modules, increase modularity, and make the code easier to maintain, test, and extend.</p>
<p>For example, consider a scenario where you have a class that needs to use an instance of another class. In the traditional approach, the first class would directly create an instance of the second class, leading to a tight coupling between them. This makes it difficult to change the implementation of the second class or to test the first class independently. </p>
<p>But if you apply the DIP, the first class would depend on an abstraction of the second class instead of the implementation. This would make it possible to easily change the implementation and test the first class independently.</p>
<p>Here is an example that violates the DIP:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WeatherTracker</span> </span>{
    <span class="hljs-keyword">private</span> String currentConditions;
    <span class="hljs-keyword">private</span> Emailer emailer;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WeatherTracker</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">this</span>.emailer = <span class="hljs-keyword">new</span> Emailer();
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCurrentConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        <span class="hljs-keyword">this</span>.currentConditions = weatherDescription;
        <span class="hljs-keyword">if</span> (weatherDescription == <span class="hljs-string">"rainy"</span>) {
            emailer.sendEmail(<span class="hljs-string">"It is rainy"</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Emailer</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">(String message)</span> </span>{
        System.out.println(<span class="hljs-string">"Email sent: "</span> + message);
    }
}
</code></pre>
<p>In this example, the <code>WeatherTracker</code> class directly creates an instance of the <code>Emailer</code> class, making it tightly coupled to the implementation. This makes it difficult to change the implementation of the <code>Emailer</code> class or to test the <code>WeatherTracker</code> class independently.</p>
<p>Here is an example of how to apply the DIP to the above code:</p>
<pre><code class="lang-java"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span></span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WeatherTracker</span> </span>{
    <span class="hljs-keyword">private</span> String currentConditions;
    <span class="hljs-keyword">private</span> Notifier notifier;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">WeatherTracker</span><span class="hljs-params">(Notifier notifier)</span> </span>{
        <span class="hljs-keyword">this</span>.notifier = notifier;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setCurrentConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        <span class="hljs-keyword">this</span>.currentConditions = weatherDescription;
        <span class="hljs-keyword">if</span> (weatherDescription == <span class="hljs-string">"rainy"</span>) {
            notifier.alertWeatherConditions(<span class="hljs-string">"It is rainy"</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Emailer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        System.out.println(<span class="hljs-string">"Email sent: "</span> + weatherDescription);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SMS</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Notifier</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">alertWeatherConditions</span><span class="hljs-params">(String weatherDescription)</span> </span>{
        System.out.println(<span class="hljs-string">"SMS sent: "</span> + weatherDescription);
    }
}
</code></pre>
<p>In this example, we created a <code>Notifier</code> interface that defines the <code>alertWeatherConditions</code> method. The <code>WeatherTracker</code> class now depends on this interface instead of the <code>Emailer</code> class, making it possible to easily change the implementation and test the <code>WeatherTracker</code> class independently. </p>
<p>We also created two implementations of the <code>Notifier</code> interface, <code>Emailer</code>, and <code>SMS</code>, to demonstrate how you can change the implementation of the <code>WeatherTracker</code> class without affecting its behavior.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>In this article, you learned about the SOLID principles which are a very important part of general Design Principles. </p>
<p>By applying these principles in your software development projects, you can create code that is easier to maintain, extend, and modify, leading to more robust, flexible, and reusable software. This will also lead to better collaboration among team members, as the code becomes more modular and easier to work with.</p>
<blockquote>
<p>For more such tutorials, you can follow <a target="_blank" href="https://blog.ashutoshkrris.in/">my personal blog</a>.</p>
</blockquote>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Open-Closed Principle – SOLID Architecture Concept Explained ]]>
                </title>
                <description>
                    <![CDATA[ The Open-Closed principle (OCP) is one the 5 SOLID design principles. It was popularized by the American computer scientist and instructor, Robert C. Martin (aka Uncle Bob) in a paper he published in 2000. The other 4 SOLID design principles are: Si... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/open-closed-principle-solid-architecture-concept-explained/</link>
                <guid isPermaLink="false">66adf1ae7550d4f37c2019bf</guid>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Wed, 22 Feb 2023 15:50:42 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/chests-34153_1280.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The Open-Closed principle (OCP) is one the 5 SOLID design principles. It was popularized by the American computer scientist and instructor, Robert C. Martin (aka Uncle Bob) in a paper he published in 2000.</p>
<p>The other 4 SOLID design principles are:</p>
<ul>
<li>Single Responsibility Principle (SRP)</li>
<li>Liskov Substitution Principle (LSP)</li>
<li>Interface Segregation Principle (ISP)</li>
<li>Dependency Inversion Principle (DIP).</li>
</ul>
<p>If you want to learn about all these principles, you can read my tutorial on the <a target="_blank" href="https://www.freecodecamp.org/news/solid-design-principles-in-software-development/">SOLID principles here</a>.</p>
<p>In this article, I’ll show you what the open-closed principle (OCP) means, why you should use it, and its implementation in JavaScript.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-the-open-closed-principle">What is the Open-Closed Principle?</a></li>
<li><a class="post-section-overview" href="#heading-why-should-you-use-the-open-closed-principle">Why should you use the Open-Closed Principle?</a></li>
<li><a class="post-section-overview" href="#heading-how-to-implement-the-open-closed-principle-in-javascript">How to implement the Open-Closed Principle in JavaScript</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-what-is-the-open-closed-principle">What is the Open-Closed Principle?</h2>
<p>The open-closed principle states that software entities (classes, modules, functions, and so on) should be open for extension, but closed for modification. </p>
<p>You are probably wondering why that statement sounds like a contradiction. Like why would something be opened and be closed at the same time? </p>
<p>Well, in the land of software development, it’s possible for an item to be opened for extension and be closed for modification. It means you or your team members should be able to add new functionalities to an existing software system without changing the existing code.</p>
<p>The open-closed principle encourages software engineers to focus on what’s necessary when it’s time to add new functionalities. </p>
<p>If you want to add new functionality to your existing code and you have to modify it before you add the new functionality, then you are not following the open-closed principle.</p>
<h2 id="heading-why-should-you-use-the-open-closed-principle">Why Should You Use the Open-Closed Principle?</h2>
<p>Here are some reasons why you should be using the open-closed principle:</p>
<ul>
<li><p><strong>You don’t need to re-invent the wheel</strong>: as the principle states, the code you and your team are working on is closed for extension. This means if you’re following the open-closed principle, you don’t need to reinvent the wheel (and rebuild everything) when you want to add new features.</p>
</li>
<li><p><strong>You focus on what is necessary</strong>: as the OCP states, your code is closed for modification. It means you can add new features without performing too much editing on the existing code, or none at all. This can help you and your team members focus on what is necessary when it’s time to implement new functionalities.</p>
</li>
<li><p><strong>You can avoid bugs</strong>: since you don’t have to edit the existing code before adding new features, you can avoid introducting unnecessary bugs.</p>
</li>
</ul>
<p>-<strong>Your code is more maintainable, testable, and flexible</strong>: following the OCP will make your codebase loosely coupled. With this the code is more flexible and maintainable. And if you want, you can unit test each class successfully. </p>
<h2 id="heading-how-to-implement-the-open-closed-principle-in-javascript">How to Implement the Open-Closed Principle in JavaScript</h2>
<p>The first example of the open-closed principle I will show is a class using a switch or multiple if statements. That’s because in code like this, there’s a very real possibility you will modify the class using the switch or if statements. And that violates the open-closed principle in the process.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Footballer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age, role) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
    <span class="hljs-built_in">this</span>.role = role;
  }

  getFootballerRole() {
    <span class="hljs-keyword">switch</span> (<span class="hljs-built_in">this</span>.role) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'goalkeeper'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The footballer, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is a goalkeeper`</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'defender'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The footballer, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is a defender`</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'midfielder'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The footballer, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is a midfielder`</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'forward'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The footballer, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> plays in the forward line`</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Unsupported animal type: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.type}</span>`</span>);
    }
  }
}

<span class="hljs-keyword">const</span> kante = <span class="hljs-keyword">new</span> Footballer(<span class="hljs-string">'Ngolo Kante'</span>, <span class="hljs-number">31</span>, <span class="hljs-string">'midfielder'</span>);
<span class="hljs-keyword">const</span> hazard = <span class="hljs-keyword">new</span> Footballer(<span class="hljs-string">'Eden Hazard'</span>, <span class="hljs-number">32</span>, <span class="hljs-string">'forward'</span>);

kante.getFootballerRole(); <span class="hljs-comment">// The footballer, Ngolo Kante is a midfielder</span>
hazard.getFootballerRole(); <span class="hljs-comment">// The footballer, Eden Hazard plays in the forward line</span>
</code></pre>
<p>There are more football roles like winger, defensive midfielder, and more. So, in the code above, what do you think would happen if you had to add another footballer role on the pitch? You would have to modify the <code>switch</code> statement. That violates the open-closed principle because you have to modify the existing code.</p>
<p>To fix the violation, you have to create a separate role <code>class</code> to consume the method that gets the player role from the super <code>class</code>. But it doesn’t end there. You then need to create a different <code>class</code> for each role that extends the class which gets the player role.</p>
<p>This will make more sense in code:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Footballer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age, role) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
    <span class="hljs-built_in">this</span>.role = role;
  }

  getRole() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.role.getRole();
  }
}

<span class="hljs-comment">// PlayerRole class uses the getRole method</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PlayerRole</span> </span>{
  getRole() {}
}

<span class="hljs-comment">// Sub classes for different roles extend the PlayerRole class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GoalkeeperRole</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PlayerRole</span> </span>{
  getRole() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'goalkeeper'</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DefenderRole</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PlayerRole</span> </span>{
  getRole() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'defender'</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MidfieldRole</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PlayerRole</span> </span>{
  getRole() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'midfielder'</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ForwardRole</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">PlayerRole</span> </span>{
  getRole() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'forward'</span>;
  }
}

<span class="hljs-comment">// Putting all of them together</span>
<span class="hljs-keyword">const</span> hazard = <span class="hljs-keyword">new</span> Footballer(<span class="hljs-string">'Hazard'</span>, <span class="hljs-number">32</span>, <span class="hljs-keyword">new</span> ForwardRole());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${hazard.name}</span> plays in the <span class="hljs-subst">${hazard.getRole()}</span> line`</span>); <span class="hljs-comment">// Hazard plays in the forward line</span>

<span class="hljs-keyword">const</span> kante = <span class="hljs-keyword">new</span> Footballer(<span class="hljs-string">'Ngolo Kante'</span>, <span class="hljs-number">31</span>, <span class="hljs-keyword">new</span> MidfieldRole());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${kante.name}</span> is the best <span class="hljs-subst">${kante.getRole()}</span> in the world!`</span>); <span class="hljs-comment">//Ngolo Kante is the best midfielder in the world!</span>
</code></pre>
<p>Here’s another example that uses functions instead of JavaScript classes:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculatePrice</span>(<span class="hljs-params">price, discount</span>) </span>{
  <span class="hljs-keyword">if</span> (discount === <span class="hljs-string">'10%'</span>) {
    <span class="hljs-keyword">return</span> price * <span class="hljs-number">0.9</span>;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (discount === <span class="hljs-string">'20%'</span>) {
    <span class="hljs-keyword">return</span> price * <span class="hljs-number">0.8</span>;
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (discount === <span class="hljs-string">'30%'</span>) {
    <span class="hljs-keyword">return</span> price * <span class="hljs-number">0.7</span>;
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Invalid discount'</span>);
  }
}

<span class="hljs-keyword">const</span> discountedPrice = calculatePrice(<span class="hljs-number">100</span>, <span class="hljs-string">'10%'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Your discounted price is <span class="hljs-subst">${discountedPrice}</span>`</span>); <span class="hljs-comment">//  The discount you get is 90</span>
</code></pre>
<p>The code above violates the open-closed principle because you have to add another <code>if…else</code> statement if you want to add a new discount.</p>
<p>To fix it, you can extract all your discounts to an object and use it in the function this way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> discounts = {
  <span class="hljs-string">'10%'</span>: <span class="hljs-number">0.9</span>,
  <span class="hljs-string">'20%'</span>: <span class="hljs-number">0.8</span>,
  <span class="hljs-string">'30%'</span>: <span class="hljs-number">0.7</span>,
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculatePrice</span>(<span class="hljs-params">price, discountType</span>) </span>{
  <span class="hljs-keyword">const</span> discount = discounts[discountType];
  <span class="hljs-keyword">if</span> (discount === <span class="hljs-literal">undefined</span>) {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Invalid discount'</span>);
  }
  <span class="hljs-keyword">return</span> price * discount;
}

<span class="hljs-keyword">const</span> discountedPrice = calculatePrice(<span class="hljs-number">100</span>, <span class="hljs-string">'30%'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Your discounted price is $<span class="hljs-subst">${discountedPrice}</span>`</span>);
</code></pre>
<p>Now if you want to add new discounts, you only need to add to the discount object, not the existing function that calculates the discount.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned about the open-closed principle, its benefits, and how to implement it.</p>
<p>To carry out the implementation, we used JavaScript classes to illustrate how you can get it done with JavaScript object-oriented programming. First I showed how the code violates the principle, and how to refactor it so it doesn't. </p>
<p>Since function is also a software entity, we also looked at how you can implement the open-closed principle with JavaScript functions.</p>
<p>Keep coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SOLID Design Principles in Software Development ]]>
                </title>
                <description>
                    <![CDATA[ SOLID is a set of five design principles. These principles help software developers design robust, testable, extensible, and maintainable object-oriented software systems.  Each of these five design principles solves a particular problem that might a... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-design-principles-in-software-development/</link>
                <guid isPermaLink="false">66adf216db5636c0b30cba8f</guid>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kolade Chris ]]>
                </dc:creator>
                <pubDate>Thu, 16 Feb 2023 17:11:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/02/start-graph--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p><strong>SOLID</strong> is a set of five design principles. These principles help software developers design robust, testable, extensible, and maintainable object-oriented software systems. </p>
<p>Each of these five design principles solves a particular problem that might arise while developing the software systems.</p>
<p>In this article, I’ll show you what the SOLID principles entail, what each part of the SOLID acronym means, and how to implement them in your code.</p>
<h2 id="heading-what-well-cover">What We'll Cover</h2>
<ul>
<li><a class="post-section-overview" href="#heading-what-are-solid-design-principles">What are SOLID Design Principles?</a><ul>
<li><a target="_blank" href="thesingleresponsibilityprinciplesrp">The Single Responsibility Principle (SRP)</a></li>
<li><a class="post-section-overview" href="#heading-the-open-closed-principle-ocp">The Open-Closed Principle (OCP)</a></li>
<li><a class="post-section-overview" href="#heading-the-liskov-substitution-principle-lsp">The Liskov Substitution Principle (LSP)</a></li>
<li><a class="post-section-overview" href="#heading-the-interface-segregation-principle-isp">The Interface Segregation Principle (ISP)</a></li>
<li><a class="post-section-overview" href="#heading-the-dependency-inversion-principle-dip">The Dependency Inversion Principle (DIP)</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a> </li>
</ul>
<h2 id="heading-what-are-solid-design-principles">What are SOLID Design Principles?</h2>
<p>SOLID is an acronym that stands for: </p>
<ul>
<li>Single Responsibility Principle (SRP)</li>
<li>Open-Closed Principle (OCP)</li>
<li>Liskov Substitution Principle (LSP)</li>
<li>Interface Segregation Principle (ISP)</li>
<li>Dependency Inversion Principle (DIP)</li>
</ul>
<p>In the coming sections, we’ll look at what each of those principles means in detail.</p>
<p>The SOLID design principles are a subcategory of many principles introduced by the American computer scientist and instructor, Robert C. Martin (A.K.A Uncle Bob) in a 2000 paper.</p>
<p>Following these principles can result in a very large codebase for a software system. But in the long run, the main aim of the principles is never defeated. That is, helping software developers make changes to their code without causing any major issues.</p>
<h3 id="heading-the-single-responsibility-principle-srp">The Single Responsibility Principle (SRP)</h3>
<p>The single responsibility principle states that a class, module, or function should have only one reason to change, meaning it should do one thing.</p>
<p>For example, a class that shows the name of an animal should not be the same class that displays the kind of sound it makes and how it feeds. </p>
<p>Here’s an example in JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, feedingType, soundMade) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.feedingType = feedingType;
    <span class="hljs-built_in">this</span>.soundMade = soundMade;
  }

  nomenclature() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The name of the animal is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }

  sound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.soundMade}</span>s`</span>);
  }

  feeding() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is a <span class="hljs-subst">${<span class="hljs-built_in">this</span>.feedingType}</span>`</span>);
  }
}

<span class="hljs-keyword">let</span> elephant = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Elephant'</span>, <span class="hljs-string">'herbivore'</span>, <span class="hljs-string">'trumpet'</span>);
elephant.nomenclature(); <span class="hljs-comment">// The name of the animal is Elephant</span>
elephant.sound(); <span class="hljs-comment">// Elephant trumpets</span>
elephant.feeding(); <span class="hljs-comment">// Elephant is a herbivore</span>
</code></pre>
<p>The code above violates the single responsibility principle because the class that's responsible for printing the name of the animal also shows the sound it makes and its type of feeding.</p>
<p>To fix this, you have to create a separate class for the sound and feeding methods like this:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  nomenclature() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`The name of the animal is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  }
}

<span class="hljs-keyword">let</span> animal1 = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Elephant'</span>);
animal1.nomenclature(); <span class="hljs-comment">// The name of the animal is Elephant</span>

<span class="hljs-comment">// Sound class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Sound</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, soundMade) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.soundMade = soundMade;
  }

  sound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> <span class="hljs-subst">${<span class="hljs-built_in">this</span>.soundMade}</span>s`</span>);
  }
}

<span class="hljs-keyword">let</span> animalSound1 = <span class="hljs-keyword">new</span> Sound(<span class="hljs-string">'Elephant'</span>, <span class="hljs-string">'trumpet'</span>);
animalSound1.sound(); <span class="hljs-comment">//Elephant trumpets</span>

<span class="hljs-comment">// Feeding class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Feeding</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, feedingType) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.feedingType = feedingType;
  }

  feeding() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is a/an <span class="hljs-subst">${<span class="hljs-built_in">this</span>.feedingType}</span>`</span>);
  }
}

<span class="hljs-keyword">let</span> animalFeeding1 = <span class="hljs-keyword">new</span> Feeding(<span class="hljs-string">'Elephant'</span>, <span class="hljs-string">'herbivore'</span>);
animalFeeding1.feeding(); <span class="hljs-comment">// Elephant is a/an herbivore</span>
</code></pre>
<p>This way, each of the classes is doing only one thing:</p>
<ul>
<li>the first one prints the name of the animal</li>
<li>the second prints the kind of sound it makes</li>
<li>and the third one prints its kind of feeding.</li>
</ul>
<p>That’s more code, but better readability and maintainability. A developer who didn’t write the code can come to it and understand what’s going on quicker than having it all in one class.</p>
<h3 id="heading-the-open-closed-principle-ocp">The Open-Closed Principle (OCP)</h3>
<p>The open-closed principle states that classes, modules, and functions should be open for extension but closed for modification.</p>
<p>This principle might seem to contradict itself, but you can still make sense of it in code. It means you should be able to extend the functionality of a class, module, or function by adding more code without modifying the existing code.</p>
<p>Here’s some code that violates the open-closed principle in JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age, type) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
    <span class="hljs-built_in">this</span>.type = type;
  }

  getSpeed() {
    <span class="hljs-keyword">switch</span> (<span class="hljs-built_in">this</span>.type) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'cheetah'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Cheetah runs up to 130mph '</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'lion'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Lion runs up to 80mph'</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">case</span> <span class="hljs-string">'elephant'</span>:
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Elephant runs up to 40mph'</span>);
        <span class="hljs-keyword">break</span>;
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Unsupported animal type: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.type}</span>`</span>);
    }
  }
}

<span class="hljs-keyword">const</span> animal1 = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Lion'</span>, <span class="hljs-number">4</span>, <span class="hljs-string">'lion'</span>);
animal1.getSpeed(); <span class="hljs-comment">// Lion runs up to 80mph</span>
</code></pre>
<p>The code above violates the open-closed principle because if you want to add a new animal type, you have to modify the existing code by adding another case to the switch statement. </p>
<p>Normally, if you’re using a <code>switch</code> statement, then it’s very likely you will violate the open-closed principle.</p>
<p>Here’s how I refactored the code to fix the problem: </p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name, age, speedRate) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
    <span class="hljs-built_in">this</span>.speedRate = speedRate;
  }

  getSpeed() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.speedRate.getSpeed();
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SpeedRate</span> </span>{
  getSpeed() {}
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CheetahSpeedRate</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SpeedRate</span> </span>{
  getSpeed() {
    <span class="hljs-keyword">return</span> <span class="hljs-number">130</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LionSpeedRate</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SpeedRate</span> </span>{
  getSpeed() {
    <span class="hljs-keyword">return</span> <span class="hljs-number">80</span>;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ElephantSpeedRate</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SpeedRate</span> </span>{
  getSpeed() {
    <span class="hljs-keyword">return</span> <span class="hljs-number">40</span>;
  }
}

<span class="hljs-keyword">const</span> cheetah = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Cheetah'</span>, <span class="hljs-number">4</span>, <span class="hljs-keyword">new</span> CheetahSpeedRate());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${cheetah.name}</span> runs up to <span class="hljs-subst">${cheetah.getSpeed()}</span> mph`</span>); <span class="hljs-comment">// Cheetah runs up to 130 mph</span>

<span class="hljs-keyword">const</span> lion = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Lion'</span>, <span class="hljs-number">5</span>, <span class="hljs-keyword">new</span> LionSpeedRate());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${lion.name}</span> runs up to <span class="hljs-subst">${lion.getSpeed()}</span> mph`</span>); <span class="hljs-comment">// Lion runs up to 80 mph</span>

<span class="hljs-keyword">const</span> elephant = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Elephant'</span>, <span class="hljs-number">10</span>, <span class="hljs-keyword">new</span> ElephantSpeedRate());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${elephant.name}</span> runs up to <span class="hljs-subst">${elephant.getSpeed()}</span> mph`</span>); <span class="hljs-comment">// Elephant runs up to 40 mph</span>
</code></pre>
<p>This way, if you want to add a new animal type, you can create a new class that extends <code>SpeedRate</code> and pass it to the Animal constructor without modifying the existing code. </p>
<p>For example, I added a new <code>GoatSpeedRate</code> class like this:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GoatSpeedRate</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SpeedRate</span> </span>{
  getSpeed() {
    <span class="hljs-keyword">return</span> <span class="hljs-number">35</span>;
  }
}

<span class="hljs-comment">// Goat</span>
<span class="hljs-keyword">const</span> goat = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Goat'</span>, <span class="hljs-number">5</span>, <span class="hljs-keyword">new</span> GoatSpeedRate());
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${goat.name}</span> runs up to <span class="hljs-subst">${goat.getSpeed()}</span> mph`</span>); <span class="hljs-comment">// Goat runs up to 354 mph</span>
</code></pre>
<p>This conforms to the open-closed principle.</p>
<h3 id="heading-the-liskov-substitution-principle-lsp">The Liskov Substitution Principle (LSP)</h3>
<p>The Liskov substitution principle is one of the most important principles to adhere to in object-oriented programming (OOP). It was introduced by the computer scientist Barbara Liskov in 1987 in a paper she co-authored with Jeannette Wing.</p>
<p>The principle states that child classes or subclasses must be substitutable for their parent classes or super classes. In other words, the child class must be able to replace the parent class. This has the advantage of letting you know what to expect from your code.</p>
<p>Here’s an example of a code that does not violate the Liskov substitution principle:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> makes a sound`</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> barks`</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> meows`</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeAnimalSound</span>(<span class="hljs-params">animal</span>) </span>{
  animal.makeSound();
}

<span class="hljs-keyword">const</span> cheetah = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Cheetah'</span>);
makeAnimalSound(cheetah); <span class="hljs-comment">// Cheetah makes a sound</span>

<span class="hljs-keyword">const</span> dog = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">'Jack'</span>);
makeAnimalSound(dog); <span class="hljs-comment">// Jack barks</span>

<span class="hljs-keyword">const</span> cat = <span class="hljs-keyword">new</span> Cat(<span class="hljs-string">'Khloe'</span>);
makeAnimalSound(cat); <span class="hljs-comment">// Khloe meows</span>
</code></pre>
<p>The <code>Dog</code> and <code>Cat</code> classes can successfully replace the parent <code>Animal</code> class.</p>
<p>On the other hand, let’s look at how the code below does violate the Liskov substitution principle:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  fly() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> flaps wings`</span>);
  }
}

<span class="hljs-keyword">const</span> parrot = <span class="hljs-keyword">new</span> Bird(<span class="hljs-string">'Titi the Parrot'</span>);
makeAnimalSound(parrot); <span class="hljs-comment">// Titi the Parrot makes a sound</span>
parrot.fly(); <span class="hljs-comment">// Titi the Parrot flaps wings</span>
</code></pre>
<p>The <code>Bird</code> class violates the Liskov substitution principle because it’s not implementing its own <code>makeSound</code> from the parent <code>Animal</code> class. Instead, it’s inheriting the generic sound.</p>
<p>To fix this, you have to make it use the <code>makeSound</code> method too:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  makeSound() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> chirps`</span>);
  }

  fly() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> flaps wings`</span>);
  }
}

<span class="hljs-keyword">const</span> parrot = <span class="hljs-keyword">new</span> Bird(<span class="hljs-string">'Titi the Parrot'</span>);
makeAnimalSound(parrot); <span class="hljs-comment">// Titi the Parrot chirps</span>
parrot.fly(); <span class="hljs-comment">// Titi the Parrot flaps wings</span>
</code></pre>
<h3 id="heading-the-interface-segregation-principle-isp">The Interface Segregation Principle (ISP)</h3>
<p>The interface segregation principle states that clients should not be forced to implement interfaces or methods they do not use. </p>
<p>More specifically, the ISP suggests that software developers should break down large interfaces into smaller, more specific ones, so that clients only need to depend on the interfaces that are relevant to them. This can make the codebase easier to maintain.</p>
<p>This principle is fairly similar to the single responsibility principle (SRP). But it’s not just about a single interface doing only one thing – it’s about breaking the whole codebase into multiple interfaces or components.</p>
<p>Think about this as the same thing you do while working with frontend frameworks and libraries like React, Svelte, and Vue. You usually break down the codebase into components you only bring in when needed. </p>
<p>This means you create individual components that have functionality specific to them. The component responsible for implementing scroll to the top, for example, will not be the one to switch between light and dark, and so on.</p>
<p>Here’s an example of code that violates the interface segregation principle:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  eat() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is eating`</span>);
  }

  swim() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is swimming`</span>);
  }

  fly() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is flying`</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Fish</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  fly() {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"ERROR! Fishes can't fly"</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  swim() {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"ERROR! Birds can't swim"</span>);
  }
}

<span class="hljs-keyword">const</span> bird = <span class="hljs-keyword">new</span> Bird(<span class="hljs-string">'Titi the Parrot'</span>);
bird.swim(); <span class="hljs-comment">// ERROR! Birds can't swim</span>

<span class="hljs-keyword">const</span> fish = <span class="hljs-keyword">new</span> Fish(<span class="hljs-string">'Neo the Dolphin'</span>);
fish.fly(); <span class="hljs-comment">// ERROR! Fishes can't fly</span>
</code></pre>
<p>The code above violates the interface segregation principle because the <code>Fish</code> class doesn’t need the <code>fly</code> method. A fish cannot fly. Birds can’t swim too, so the <code>Bird</code> class doesn’t need the <code>swim</code> method.</p>
<p>Also, the <code>Bird</code> and <code>Fish</code> classes both extend the <code>Animal</code> class, and that violates the ISP since the <code>Animal</code> class has methods that either class does not need. </p>
<p>The goal is to create interfaces that are tailored to the specific needs of each class/functionality.</p>
<p>This is how I fixed the code to conform to the interface segregation principle:</p>
<pre><code class="lang-js"><span class="hljs-comment">// Define interfaces for different types of animals</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Swimmer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  swim() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is swimming`</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Flyer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  fly() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is flying`</span>);
  }
}

<span class="hljs-comment">// Implement interfaces for specific types of animals</span>

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Flyer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">super</span>(name);
  }

  eat() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is eating`</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Fish</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Swimmer</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">super</span>(name);
  }

  eat() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is eating`</span>);
  }
}

<span class="hljs-comment">// Usage</span>

<span class="hljs-keyword">const</span> bird = <span class="hljs-keyword">new</span> Bird(<span class="hljs-string">'Titi the Parrot'</span>);
bird.fly(); <span class="hljs-comment">// Titi the Parrot is flying</span>
bird.eat(); <span class="hljs-comment">// Titi the Parrot is eating</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'\n'</span>);

<span class="hljs-keyword">const</span> fish = <span class="hljs-keyword">new</span> Fish(<span class="hljs-string">'Neo the Dolphin'</span>);
fish.swim(); <span class="hljs-comment">// Neo the Dolphin is swimming</span>
fish.eat(); <span class="hljs-comment">// Neo the Dolphin is eating</span>
</code></pre>
<p>In the code above, we have a class specifically for animals that swim and another for animals that fly. The <code>Fish</code> and <code>Bird</code> classes only extend classes with  methods specific to their needs.</p>
<h3 id="heading-the-dependency-inversion-principle-dip">The Dependency Inversion Principle (DIP)</h3>
<p>The dependency inversion principle is about decoupling software modules. That is, making them as separate from one another as possible.</p>
<p>The principle states that high-level modules should not depend on low-level modules. Instead, they should both depend on abstractions. Additionally, abstractions should not depend on details, but details should depend on abstractions.</p>
<p>In simpler terms, this means instead of writing code that relies on specific details of how lower-level code works, you should write code that depends on more general abstractions that can be implemented in different ways. </p>
<p>This makes it easier to change the lower-level code without having to change the higher-level code.</p>
<p>Here’s a code that violates the dependency inversion principle:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  bark() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'woof! woof!! woof!!'</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  meow() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'meooow!'</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printAnimalNames</span>(<span class="hljs-params">animals</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; animals.length; i++) {
    <span class="hljs-keyword">const</span> animal = animals[i];
    <span class="hljs-built_in">console</span>.log(animal.name);
  }
}

<span class="hljs-keyword">const</span> dog = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">'Jack'</span>);
<span class="hljs-keyword">const</span> cat = <span class="hljs-keyword">new</span> Cat(<span class="hljs-string">'Zoey'</span>);

<span class="hljs-keyword">const</span> animals = [dog, cat];

printAnimalNames(animals);
</code></pre>
<p>The code above violates dependency inversion principle because the <code>printAnimalNames</code> function depends on the concrete implementations of Dog and Cat. </p>
<p>If you wanted to add another animal like an ape, you’d have to modify the <code>printAnimalNames</code> function to handle it.</p>
<p>Here’s how to fix it:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  getName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.name;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  bark() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'woof! woof!! woof!!!'</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  meow() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'meooow!'</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printAnimalNames</span>(<span class="hljs-params">animals</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; animals.length; i++) {
    <span class="hljs-keyword">const</span> animal = animals[i];
    <span class="hljs-built_in">console</span>.log(animal.getName());
  }
}

<span class="hljs-keyword">const</span> dog = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">'Jack'</span>);
<span class="hljs-keyword">const</span> cat = <span class="hljs-keyword">new</span> Cat(<span class="hljs-string">'Zoey'</span>);

<span class="hljs-keyword">const</span> animals = [dog, cat, ape];

printAnimalNames(animals);
</code></pre>
<p>In the code above, I created a <code>getName</code> method inside the Animal class. This provides an abstraction that the <code>printAnimalNames</code> function can depend on. Now, the <code>printAnimalNames</code> function only depends on the <code>Animal</code> class, not the concrete implementations of <code>Dog</code> and <code>Cat</code>.</p>
<p>If you wan to add an Ape class, you can do so without modifying the <code>printAnimalNames</code> function:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  getName() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.name;
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  bark() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'woof! woof!! woof!!!'</span>);
  }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  meow() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'meooow!'</span>);
  }
}

<span class="hljs-comment">// Add Ape class</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Ape</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Animal</span> </span>{
  meow() {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'woo! woo! woo!'</span>);
  }
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printAnimalNames</span>(<span class="hljs-params">animals</span>) </span>{
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; animals.length; i++) {
    <span class="hljs-keyword">const</span> animal = animals[i];
    <span class="hljs-built_in">console</span>.log(animal.getName());
  }
}

<span class="hljs-keyword">const</span> dog = <span class="hljs-keyword">new</span> Dog(<span class="hljs-string">'Jack'</span>); <span class="hljs-comment">// Jack</span>
<span class="hljs-keyword">const</span> cat = <span class="hljs-keyword">new</span> Cat(<span class="hljs-string">'Zoey'</span>); <span class="hljs-comment">// Zoey</span>

<span class="hljs-comment">// Use the Ape class</span>
<span class="hljs-keyword">const</span> ape = <span class="hljs-keyword">new</span> Ape(<span class="hljs-string">'King Kong'</span>); <span class="hljs-comment">// King Kong</span>

<span class="hljs-keyword">const</span> animals = [dog, cat, ape];

printAnimalNames(animals);
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you learned what the <strong>SOLID</strong> design priniples are. We discussed each principle with an example, and went through ways to implement them in JavaScript.</p>
<p>I hope the article gives you a solid grasp of the <strong>SOLID</strong> principles. You can see that the SOLID design principles can help you create a software system that is free of bugs, maintainable, flexible, scalable, and reusable.</p>
<p>Thanks for reading.princip</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SOLID Principles for Programming and Software Design ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID principles of object-oriented programming help make object-oriented designs more understandable, flexible, and maintainable. They also make it easy to create readable and testable code that many developers can collaboratively work with anyw... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-for-programming-and-software-design/</link>
                <guid isPermaLink="false">66d45ff4230dff0166905821</guid>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software architecture ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software design ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Joel Olawanle ]]>
                </dc:creator>
                <pubDate>Wed, 09 Nov 2022 22:43:45 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/11/Untitled1.drawio--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The SOLID principles of object-oriented programming help make object-oriented designs more understandable, flexible, and maintainable.</p>
<p>They also make it easy to create readable and testable code that many developers can collaboratively work with anywhere and anytime. And they make you aware of the best way to write code 💪.</p>
<p>SOLID is a mnemonic acronym that stands for the five design principles of Object-Oriented class design. These principles are:</p>
<ul>
<li><p><strong>S</strong> - Single-responsibility Principle</p>
</li>
<li><p><strong>O</strong> - Open-closed Principle</p>
</li>
<li><p><strong>L</strong> - Liskov Substitution Principle</p>
</li>
<li><p><strong>I</strong> - Interface Segregation Principle</p>
</li>
<li><p><strong>D</strong> - Dependency Inversion Principle</p>
</li>
</ul>
<p>In this article, you will learn what these principles stand for and how they work using JavaScript examples. The examples should be fine even if you are not fully conversant with JavaScript, because they apply to other programming languages as well.</p>
<h2 id="heading-what-is-the-single-responsibility-principle-srp">What is the Single-Responsibility Principle (SRP)?</h2>
<p>The Single-responsibility Principle, or SRP, states that a class should only have one reason to change. This means that a class should have only one job and do one thing.</p>
<p>Let’s take a look at a proper example. You’ll always be tempted to put similar classes together – but unfortunately, this goes against the Single-responsibility principle. Why?</p>
<p>The <code>ValidatePerson</code> object below has three methods: two validation methods, (<code>ValidateName()</code> and <code>ValidateAge()</code>), and a <code>Display()</code> method.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidatePerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
    }

    ValidateName(name) {
        <span class="hljs-keyword">if</span> (name.length &gt; <span class="hljs-number">3</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    ValidateAge(age) {
        <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">18</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    Display() {
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.ValidateName(<span class="hljs-built_in">this</span>.name) &amp;&amp; <span class="hljs-built_in">this</span>.ValidateAge(<span class="hljs-built_in">this</span>.age)) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Name: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and Age: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid'</span>);
        }
    }
}
</code></pre>
<p>The <code>Display()</code> method goes against the SRP because the goal is that a class should have only one job and do one thing. The <code>ValidatePerson</code> class does two jobs – it validates the person’s name and age and then displays some information.</p>
<p>The way to avoid this problem is to separate code that supports different actions and jobs so that each class only performs one job and has one reason to change.</p>
<p>This means that the <code>ValidatePerson</code> class will only be responsible for validating a user, as seen below:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ValidatePerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
    }

    ValidateName(name) {
        <span class="hljs-keyword">if</span> (name.length &gt; <span class="hljs-number">3</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }

    ValidateAge(age) {
        <span class="hljs-keyword">if</span> (age &gt; <span class="hljs-number">18</span>) {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
        }
    }
}
</code></pre>
<p>While the new class <code>DisplayPerson</code> will now be responsible for displaying a person, as you can see in the code block below:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DisplayPerson</span> </span>{
    <span class="hljs-keyword">constructor</span>(name, age) {
        <span class="hljs-built_in">this</span>.name = name;
        <span class="hljs-built_in">this</span>.age = age;
        <span class="hljs-built_in">this</span>.validate = <span class="hljs-keyword">new</span> ValidatePerson(<span class="hljs-built_in">this</span>.name, <span class="hljs-built_in">this</span>.age);
    }

    Display() {
        <span class="hljs-keyword">if</span> (
            <span class="hljs-built_in">this</span>.validate.ValidateName(<span class="hljs-built_in">this</span>.name) &amp;&amp;
            <span class="hljs-built_in">this</span>.validate.ValidateAge(<span class="hljs-built_in">this</span>.age)
        ) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Name: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and Age: <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span>`</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Invalid'</span>);
        }
    }
}
</code></pre>
<p>With this, you will have fulfilled the single-responsibility principle, meaning our classes now have just one reason to change. If you want to change the <code>DisplayPerson</code> class, it won’t affect the <code>ValidatePerson</code> class.</p>
<h2 id="heading-what-is-the-open-closed-principle">What is the Open-Closed Principle?</h2>
<p>The open-closed principle can be confusing because it's a two-direction principle. According to <a target="_blank" href="https://en.wikipedia.org/wiki/Bertrand_Meyer">Bertrand Meyer's</a> definition on <a target="_blank" href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a>, the <strong>open-closed principle (OCP)</strong> states that software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.</p>
<p>This definition can be confusing, but an example and further clarification will help you understand.</p>
<p>There are two primary attributes in the OCP:</p>
<ul>
<li><p>It is <strong>open</strong> for extension — This means you can extend what the module can do.</p>
</li>
<li><p>It is <strong>closed</strong> for modification — This means you cannot change the source code, even though you can extend the behavior of a module or entity.</p>
</li>
</ul>
<p>OCP means that a class, module, function, and other entities can extend their behavior without modifying their source code. In other words, an entity should be extendable without modifying the entity itself. How?</p>
<p>For example, suppose you have an array of <code>iceCreamFlavours</code>, which contains a list of possible flavors. In the <code>makeIceCream</code> class, a <code>make()</code> method will check if a particular flavor exists and logs a message.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> iceCreamFlavors = [<span class="hljs-string">'chocolate'</span>, <span class="hljs-string">'vanilla'</span>];

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">makeIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }

    make() {
        <span class="hljs-keyword">if</span> (iceCreamFlavors.indexOf(<span class="hljs-built_in">this</span>.flavor) &gt; <span class="hljs-number">-1</span>) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Great success. You now have ice cream.'</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Epic fail. No ice cream for you.'</span>);
        }
    }
}
</code></pre>
<p>The code above fails the OCP principle. Why? Well, because the code above is not open to an extension, meaning for you to add new flavors, you would need to directly edit the <code>iceCreamFlavors</code> array. This means that the code is no longer closed to modification. Haha (that's a lot).</p>
<p>To fix this, you would need an extra class or entity to handle addition, so you no longer need to modify the code directly to make any extension.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> iceCreamFlavors = [<span class="hljs-string">'chocolate'</span>, <span class="hljs-string">'vanilla'</span>];

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">makeIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }
    make() {
        <span class="hljs-keyword">if</span> (iceCreamFlavors.indexOf(<span class="hljs-built_in">this</span>.flavor) &gt; <span class="hljs-number">-1</span>) {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Great success. You now have ice cream.'</span>);
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Epic fail. No ice cream for you.'</span>);
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">addIceCream</span> </span>{
    <span class="hljs-keyword">constructor</span>(flavor) {
        <span class="hljs-built_in">this</span>.flavor = flavor;
    }
    add() {
        iceCreamFlavors.push(<span class="hljs-built_in">this</span>.flavor);
    }
}
</code></pre>
<p>Here, we've added a new class — <code>addIceCream</code> – to handle addition to the <code>iceCreamFlavors</code> array using the <code>add()</code> method. This means your code is closed to modification but open to an extension because you can add new flavors without directly affecting the array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> addStrawberryFlavor = <span class="hljs-keyword">new</span> addIceCream(<span class="hljs-string">'strawberry'</span>);
addStrawberryFlavor.add();
makeStrawberryIceCream.make();
</code></pre>
<p>Also, notice that SRP is in place because you created a new class. 😊</p>
<h2 id="heading-what-is-the-liskov-substitution-principle">What is the Liskov Substitution Principle?</h2>
<p>In 1987, the Liskov Substitution Principle (LSP) was introduced by <a target="_blank" href="https://en.wikipedia.org/wiki/Barbara_Liskov">Barbara Liskov</a> in her conference keynote “Data abstraction”. A few years later, she defined the principle like this:</p>
<blockquote>
<p>“Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T”.</p>
</blockquote>
<p>To be honest, that definition is not what many software developers want to see 😂 — so let me break it down into an OOP-related definition.</p>
<p>The principle defines that in an inheritance, objects of a superclass (or parent class) should be substitutable with objects of its subclasses (or child class) without breaking the application or causing any error.</p>
<p>In very plain terms, you want the objects of your subclasses to behave the same way as the objects of your superclass.</p>
<p>A very common example is the rectangle, square scenario. It’s clear that all squares are rectangles because they are quadrilaterals with all four angles being right angles. But not every rectangle is a square. To be a square, its sides must have the same length.</p>
<p>Bearing this in mind, suppose you have a rectangle class to calculate the area of a rectangle and perform other operations like set color:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
    }

    setHeight(height) {
        <span class="hljs-built_in">this</span>.height = height;
    }

    setColor(color) {
        <span class="hljs-comment">// ...</span>
    }

    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.width * <span class="hljs-built_in">this</span>.height;
    }
}
</code></pre>
<p>Knowing fully well that all squares are rectangles, you can inherit the properties of the rectangle. Since the width and height has to be the same, then you can adjust it:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Rectangle</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
        <span class="hljs-built_in">this</span>.height = width;
    }
    setHeight(height) {
        <span class="hljs-built_in">this</span>.width = height;
        <span class="hljs-built_in">this</span>.height = height;
    }
}
</code></pre>
<p>Taking a look at the example, it should work properly:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> rectangle = <span class="hljs-keyword">new</span> Rectangle();
rectangle.setWidth(<span class="hljs-number">10</span>);
rectangle.setHeight(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(rectangle.getArea()); <span class="hljs-comment">// 50</span>
</code></pre>
<p>In the above, you will notice that a rectangle is created, and the width and height are set. Then you can calculate the correct area.</p>
<p>But according to the LSP, you want the objects of your subclasses to behave the same way as the objects of your superclass. Meaning if you replace the <code>Rectangle</code> with <code>Square</code>, everything should still work well:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setWidth(<span class="hljs-number">10</span>);
square.setHeight(<span class="hljs-number">5</span>);
</code></pre>
<p>You should get 100, because the <code>setWidth(10)</code> is supposed to set both the width and height to 10. But because of the <code>setHeight(5)</code>, this will return 25.</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setWidth(<span class="hljs-number">10</span>);
square.setHeight(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(square.getArea()); <span class="hljs-comment">// 25</span>
</code></pre>
<p>This breaks the LSP. To fix this, there should be a general class for all shapes that will hold all generic methods that you want the objects of your subclasses to have access to. Then for individual methods, you create an individual class for rectangle and square.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span> </span>{
    setColor(color) {
        <span class="hljs-built_in">this</span>.color = color;
    }
    getColor() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.color;
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Shape</span> </span>{
    setWidth(width) {
        <span class="hljs-built_in">this</span>.width = width;
    }
    setHeight(height) {
        <span class="hljs-built_in">this</span>.height = height;
    }
    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.width * <span class="hljs-built_in">this</span>.height;
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Shape</span> </span>{
    setSide(side) {
        <span class="hljs-built_in">this</span>.side = side;
    }
    getArea() {
        <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.side * <span class="hljs-built_in">this</span>.side;
    }
}
</code></pre>
<p>This way, you can set the color and get the color using either the super or subclasses:</p>
<pre><code class="lang-js"><span class="hljs-comment">// superclass</span>
<span class="hljs-keyword">let</span> shape = <span class="hljs-keyword">new</span> Shape();
shape.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(shape.getColor()); <span class="hljs-comment">// red</span>

<span class="hljs-comment">// subclass</span>
<span class="hljs-keyword">let</span> rectangle = <span class="hljs-keyword">new</span> Rectangle();
rectangle.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(rectangle.getColor()); <span class="hljs-comment">// red</span>

<span class="hljs-comment">// subclass</span>
<span class="hljs-keyword">let</span> square = <span class="hljs-keyword">new</span> Square();
square.setColor(<span class="hljs-string">'red'</span>);
<span class="hljs-built_in">console</span>.log(square.getColor()); <span class="hljs-comment">// red</span>
</code></pre>
<h2 id="heading-what-is-the-interface-segregation-principle">What is the Interface Segregation Principle?</h2>
<p>The Interface Segregation Principle (ISP) states that “a client should never be forced to implement an interface that it doesn’t use, or clients shouldn’t be forced to depend on methods they do not use”. What does this mean?</p>
<p>Just as the term segregation means — this is all about keeping things separated, meaning separating the interfaces.</p>
<p><strong>Note:</strong> By default, JavaScript does not have interfaces, but this principle still applies. So let’s explore this as if the interface exists, so you will know how it works for other programming languages like Java.</p>
<p>A typical interface will contain methods and properties. When you implement this interface into any class, then the class needs to define all its methods. For example, suppose you have an interface that defines methods to draw specific shapes.</p>
<pre><code class="lang-js">interface ShapeInterface {
    calculateArea();
    calculateVolume();
}
</code></pre>
<p>When any class implements this interface, all the methods must be defined even if you won't use them or if they don’t apply to that class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }  
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cuboid</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }    
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }   
}
</code></pre>
<p>Looking at the example above, you will notice that you cannot calculate the volume of a square or rectangle. Because the class implements the interface, you need to define all methods, even the ones you won’t use or need.</p>
<p>To fix this, you would need to segregate the interface.</p>
<pre><code class="lang-js">interface ShapeInterface {
    calculateArea();
}

interface ThreeDimensionalShapeInterface {
    calculateArea();
    calculateVolume();
}
</code></pre>
<p>You can now implement the specific interface that works with each class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Square</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    } 
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Cuboid</span> <span class="hljs-title">implements</span> <span class="hljs-title">ThreeDimensionalShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }
    calculateVolume(){
        <span class="hljs-comment">//...</span>
    }    
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> <span class="hljs-title">implements</span> <span class="hljs-title">ShapeInterface</span> </span>{
    calculateArea(){
        <span class="hljs-comment">//...</span>
    }  
}
</code></pre>
<h2 id="heading-what-is-the-dependency-inversion-principle">What is the Dependency Inversion Principle?</h2>
<p>This principle is targeted towards loosely coupling software modules so that high-level modules (which provide complex logic) are easily reusable and unaffected by changes in low-level modules (which provide utility features).</p>
<p>According to <a target="_blank" href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a>, this principle states that:</p>
<ol>
<li><p>High-level modules should not import anything from low-level modules. Both should depend on abstractions (for example, interfaces).</p>
</li>
<li><p>Abstractions should be independent of details. Details (concrete implementations) should depend on abstractions.</p>
</li>
</ol>
<p>In plain terms, this principle states that your classes should depend upon interfaces or abstract classes instead of concrete classes and functions. This makes your classes open to extension, following the open-closed principle.</p>
<p>Let's look at an example. When building a store, you would want your store to make use of a payment gateway like stripe or any other preferred payment method. You might write your code tightly coupled to that API without thinking of the future.</p>
<p>But then what if you discover another payment gateway that offers far better service, let’s say PayPal? Then it becomes a struggle to switch from Stripe to Paypal, which should not be an issue in programming and software design.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.stripe = <span class="hljs-keyword">new</span> Stripe(user);
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(price * quantity);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(price * quantity);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stripe</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
    }

    makePayment(amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}
</code></pre>
<p>Considering the example above, you'll notice that if you change the payment gateway, you won't just need to add the class – you'll also need to make changes to the <code>Store</code> class. This does not just go against the Dependency Inversion Principle but also against the open-closed principle.</p>
<p>To fix this, you must ensure that your classes depend upon interfaces or abstract classes instead of concrete classes and functions. For this example, this interface will contain all the behavior you want your API to have and doesn't depend on anything. It serves as an intermediary between the high-level and low-level modules.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(paymentProcessor) {
        <span class="hljs-built_in">this</span>.paymentProcessor = paymentProcessor;
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StripePaymentProcessor</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.stripe = <span class="hljs-keyword">new</span> Stripe(user);
    }

    pay(amountInDollars) {
        <span class="hljs-built_in">this</span>.stripe.makePayment(amountInDollars);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stripe</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
    }

    makePayment(amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}

<span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store(<span class="hljs-keyword">new</span> StripePaymentProcessor(<span class="hljs-string">'John Doe'</span>));
store.purchaseBook(<span class="hljs-number">2</span>, <span class="hljs-number">10</span>);
store.purchaseCourse(<span class="hljs-number">1</span>, <span class="hljs-number">15</span>);
</code></pre>
<p>In the code above, you will notice that the <code>StripePaymentProcessor</code> class is an interface between the <code>Store</code> class and the <code>Stripe</code> class. In a situation where you need to make use of PayPal, all you have to do is create a <code>PayPalPaymentProcessor</code> which would work with the <code>PayPal</code> class, and everything will work without affecting the <code>Store</code> class.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Store</span> </span>{
    <span class="hljs-keyword">constructor</span>(paymentProcessor) {
        <span class="hljs-built_in">this</span>.paymentProcessor = paymentProcessor;
    }

    purchaseBook(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }

    purchaseCourse(quantity, price) {
        <span class="hljs-built_in">this</span>.paymentProcessor.pay(quantity * price);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PayPalPaymentProcessor</span> </span>{
    <span class="hljs-keyword">constructor</span>(user) {
        <span class="hljs-built_in">this</span>.user = user;
        <span class="hljs-built_in">this</span>.paypal = <span class="hljs-keyword">new</span> PayPal();
    }

    pay(amountInDollars) {
        <span class="hljs-built_in">this</span>.paypal.makePayment(<span class="hljs-built_in">this</span>.user, amountInDollars);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">PayPal</span> </span>{
    makePayment(user, amountInDollars) {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${user}</span> made payment of <span class="hljs-subst">${amountInDollars}</span>`</span>);
    }
}

<span class="hljs-keyword">let</span> store = <span class="hljs-keyword">new</span> Store(<span class="hljs-keyword">new</span> PayPalPaymentProcessor(<span class="hljs-string">'John Doe'</span>));
store.purchaseBook(<span class="hljs-number">2</span>, <span class="hljs-number">10</span>);
store.purchaseCourse(<span class="hljs-number">1</span>, <span class="hljs-number">15</span>);
</code></pre>
<p>You will also notice that this follows the Liskov Substitution Principle because you can replace it with other implementations of the same interface without breaking your application.</p>
<h2 id="heading-ta-da">Ta-Da 😇</h2>
<p>It's been an adventure🙃. I hope you noticed that each of these principles are related to the others in some way.</p>
<p>In an attempt to correct one principle, say the dependency inversion principle, you indirectly ensure that your classes are open to extension but closed to modification, for example.</p>
<p>You should keep these principles in mind when writing code, because they make it easier for many people to collaborate on your project. They simplify the process of extending, modifying, testing, and refactoring your code. So make sure you understand their definitions, what they do, and why you need them beyond OOP.</p>
<p>For more understanding, you can watch <a target="_blank" href="https://www.youtube.com/watch?v=XzdhzyAukMM">this video</a> by <a target="_blank" href="https://www.freecodecamp.org/news/author/beau/">Beau Carnes</a> on the <a target="_blank" href="https://www.youtube.com/c/Freecodecamp">freeCodeCamp YouTube channel</a> or read <a target="_blank" href="https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/">this article</a> by <a target="_blank" href="https://www.freecodecamp.org/news/author/erinc/">Yiğit Kemal Erinç</a>.</p>
<p>Have fun coding!</p>
<p>You can access over 200 of my articles by <a target="_blank" href="https://joelolawanle.com/contents">visiting my website</a>. You can also use the search field to see if I've written a specific article.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ SOLID Definition – the SOLID Principles of Object-Oriented Design Explained ]]>
                </title>
                <description>
                    <![CDATA[ The SOLID design principles help us create maintainable, reusable, and flexible software designs. Each letter in the acronym SOLID stands for a specific principle.  Here is what each letter in the acronym stands for: S: Single responsibility princip... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solid-principles-single-responsibility-principle-explained/</link>
                <guid isPermaLink="false">66b0a3613dc92ea6a5a091ef</guid>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ solid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ihechikara Abba ]]>
                </dc:creator>
                <pubDate>Tue, 26 Apr 2022 21:16:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/solid.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The <strong>SOLID</strong> design principles help us create maintainable, reusable, and flexible software designs. Each letter in the acronym <strong>SOLID</strong> stands for a specific principle. </p>
<p>Here is what each letter in the acronym stands for:</p>
<ul>
<li><strong>S</strong>: Single responsibility principle.</li>
<li><strong>O</strong>: Open–closed principle.</li>
<li><strong>L</strong>: Liskov substitution principle.</li>
<li><strong>I</strong>: Interface segregation principle.</li>
<li><strong>D</strong>: Dependency inversion principle.</li>
</ul>
<p>In this article, we'll start by defining each principle and then we'll see some examples to help you understand how and why you should use these principles in your code. </p>
<p>The examples we will use in this article are going to be very basic. We will be using Java for our examples.</p>
<p>We'll conclude this article by talking about the basics of object oriented design.</p>
<h2 id="heading-the-single-responsibility-principle-srp">The Single Responsibility Principle (SRP)</h2>
<p>The idea behind the SRP is that every class, module, or function in a program should have one responsibility/purpose in a program. As a commonly used definition, "every class should have only one reason to change". </p>
<p>Consider the example below:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> </span>{

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">registerStudent</span><span class="hljs-params">()</span> </span>{
         <span class="hljs-comment">// some logic</span>
     }

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">calculate_Student_Results</span><span class="hljs-params">()</span> </span>{
         <span class="hljs-comment">// some logic</span>
     }

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">()</span> </span>{
         <span class="hljs-comment">// some logic</span>
     }

}
</code></pre>
<p>The class above violates the single responsibility principle. Why?</p>
<p>This <code>Student</code> class has three responsibilities – registering students, calculating their results, and sending out emails to students.</p>
<p>The code above will work perfectly but will lead to some challenges. We cannot make this code reusable for other classes or objects. The class has a whole lot of logic interconnected that we would have a hard time fixing errors. And as the codebase grows, so does the logic, making it even harder to understand what is going on. </p>
<p>Imagine a new developer joining a team with this sort of logic with a codebase of about two thousand lines of code all congested into one class. </p>
<p>Now let's fix this!</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentRegister</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">registerStudent</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// some logic</span>
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentResult</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">calculate_Student_Result</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// some logic</span>
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">StudentEmails</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">sendEmail</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// some logic</span>
    }
}
</code></pre>
<p>Now we've separated each functionality in our program. We can call the classes anywhere we want to use them in our code. </p>
<p>The examples we used use just showed each class having one method – this is mainly for simplicity. You can have as many methods as you want but they should be linked to the responsibility of the class.</p>
<p>Now that we have separated the logic, our code is easier to understand as each core functionality has its own class. We can test for errors more efficiently.</p>
<p>The code is now reusable. Before, we could only use these functionalities inside one class but now they can be used in any class. </p>
<p>The code is also easily maintainable and scalable because instead of reading interconnected lines of code, we have separated concerns so we can focus on the features we want to work on.</p>
<h2 id="heading-openclosed-principle-ocp">Open–Closed Principle (OCP)</h2>
<p>The open-closed principle states that software entities should be open for extension, but closed for modification. </p>
<p>This implies that such entities – classes, functions, and so on – should be created in a way that their core functionalities can be extended to other entities without altering the initial entity's source code. </p>
<p>In the example below, we're going to write the code for calculating the body mass index (BMI) of a person:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Human</span>  </span>{

     <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> height;
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> weight;

}
</code></pre>
<p>We've created the <code>Human</code> class which provides the <code>height</code> and <code>width</code> properties of the class. Now, let's calculate the first person's BMI.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CalculateBMI</span> </span>{

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">CALCULATE_JOHN_BMI</span><span class="hljs-params">(Human John)</span> </span>{   

         <span class="hljs-keyword">return</span> John.height/John.weight;

     }
}
</code></pre>
<p>We've calculate the BMI of a person named <code>John</code>. We'll go on and calculate the BMI for a person named <code>Jane</code>. </p>
<pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CalculateBMI</span> </span>{

     public int CALCULATE_JOHN_BMI(Human John) {   

         <span class="hljs-keyword">return</span> John.height/John.weight;

     }

     public int CALCULATE_JANE_BMI(Human Jane) {   

         <span class="hljs-keyword">return</span> Jane.height/Jane.weight;

     }
}
</code></pre><p>The problem with this is that we keep modifying the code every time we need to calculate the BMI of another person. </p>
<p>This also violates the SRP because the class now has more than one reason to change.</p>
<p>Although the code above may work perfectly, it's not efficient. We modify the code constantly which may lead to bugs. And the code only has provision for humans. What if we have to calculate for an animal or an object?</p>
<p>Let's fix the problem using the open-closed principle.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Entity</span> </span>{

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">CalculateBMI</span><span class="hljs-params">()</span></span>;

}

<span class="hljs-comment">// John entity</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">John</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Entity</span> </span>{

     <span class="hljs-keyword">int</span> height;
     <span class="hljs-keyword">int</span> weight;

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateBMI</span><span class="hljs-params">()</span> </span>{

           <span class="hljs-keyword">return</span> John.height/John.weight;
     }
}

<span class="hljs-comment">// Jane entity</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Jane</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Entity</span> </span>{

     <span class="hljs-keyword">int</span> height;
     <span class="hljs-keyword">int</span> weight;

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateBMI</span><span class="hljs-params">()</span> </span>{

           <span class="hljs-keyword">return</span> Jane.height/Jane.weight;
     }
}

<span class="hljs-comment">// Dog entity</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Entity</span> </span>{

     <span class="hljs-keyword">int</span> height;
     <span class="hljs-keyword">int</span> weight;

     <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateBMI</span><span class="hljs-params">()</span> </span>{

           <span class="hljs-keyword">return</span> Dog.height/Dog.weight;
     }
}
</code></pre>
<p>In the code above, we have created an interface called <code>Entity</code> with a <code>CalculateBMI()</code> method. </p>
<p>Each entity – <code>John</code>, <code>Jane</code> and <code>Dog</code> – extends the functionality of the <code>Entity</code> interface. </p>
<p>Now we no longer have to modify existing code when we create a new entity - we just extend the functionality we need and apply it to the new entity. </p>
<p>Next, we'll talk about the Liskov Substitution Principle. </p>
<h2 id="heading-liskov-substitution-principle-lsp">Liskov Substitution Principle (LSP)</h2>
<p>According to Barbara Liskov and Jeannette Wing, the Liskov substitution principle states that:</p>
<blockquote>
<p><em>Let </em>Φ(x)_ be a property provable about objects <em>x</em> of type <em>T</em>. Then <em>Φ(y)</em> should be true for objects <em>y</em> of type <em>S</em> where <em>S</em> is a subtype of <em>T</em>. (Source:_ <a target="_blank" href="https://en.wikipedia.org/wiki/Liskov_substitution_principle#:~:text=Subtype%20Requirement%3A%20Let,a%20subtype%20of%20T">Wikipedia</a><em>)</em></p>
</blockquote>
<p>Don't worry if you find that confusing, it will all make sense soon. Let's simplify this principle below:</p>
<p>The Liskov substitution principle simply implies that when an instance of a class is passed/extended to another class, the inheriting class should have a use case for all the properties and behavior of the inherited class.</p>
<p>Let's say we have a class called <code>Amphibian</code> for animals that can live on both land and water. This class has two methods to show the features of an amphibian – <code>swim()</code> and <code>walk()</code>. </p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Amphibian</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">swim</span><span class="hljs-params">()</span></span>;
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">walk</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<p>The <code>Amphibian</code> class can extend to a <code>Frog</code> class because frogs are amphibians, so they can inherit the properties of the <code>Amphibian</code> class without altering the logic and purpose of the class.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Frog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Amphibian</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">swim</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"The frog is swimming"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">walk</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"The frog is walking on land"</span>);
    }
}
</code></pre>
<p>But we cannot extend the <code>Amphibian</code> class to a <code>Dolphin</code> class because dolphins only live in water which implies that the <code>walk()</code> method would be irrelevant to the <code>Dolphin</code> class.</p>
<p>So, when you extend a class, if some of the properties of the initial class are not useful for the new class, the Liskov substitution principle has been violated.</p>
<p>The solution to this is simple: create interfaces that match the needs of the inheriting class.</p>
<p>In summary, if a class inherits another, it should do so in a manner that all the properties of the inherited class would remain relevant to its functionality.</p>
<h2 id="heading-interface-segregation-principle-isp">Interface Segregation Principle (ISP)</h2>
<p>The interface segregation principle states that the interface of a program should be split in a way that the user/client would only have access to the necessary methods related to their needs. </p>
<p>To understand this better, we'll first look at an example that violates the ISP:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">English</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Biology</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Chemistry</span><span class="hljs-params">()</span></span>;

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Mathematics</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<p>We've created an interface called <code>Teacher</code> which has various subjects as its methods. Let's extend this interface to our first teacher. </p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Jane</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">English</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Jane is teaching the students English language."</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Biology</span><span class="hljs-params">()</span> </span>{
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Chemistry</span><span class="hljs-params">()</span> </span>{
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Mathematics</span><span class="hljs-params">()</span> </span>{
    }
}
</code></pre>
<p>From the code above, you can tell that <code>Jane</code> is an English teacher who has no business with the other subjects. But these other methods are extended by default with the <code>Teacher</code> interface. </p>
<p>Do not confuse the Liskov substitution principle and the interface segregation principle. They may seem similar but they are not entirely the same.</p>
<p>Liskov substitution principle gives us the idea that when a new class has the need to inherit an existing class, it should do so because this new class has a need for the methods the existing class has.</p>
<p>On the other hand, the interface segregation principle makes us understand that it is unnecessary and unreasonable to create an interface with a lot of methods as some of these methods may be irrelevant to the needs of a particular user when extended.</p>
<p>Now let's fix the code in the last example.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Teach</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<p>The <code>Teacher</code> interface now has only one method. Let's go on and extend this interface to support the different subjects. </p>
<pre><code class="lang-java"><span class="hljs-comment">// English teacher interface</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">EnglishTeacher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">English</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<pre><code class="lang-java"><span class="hljs-comment">// Biology teacher interface</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">BiologyTeacher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Bilogy</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<pre><code class="lang-java"><span class="hljs-comment">// Chemistry teacher interface</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ChemistryTeacher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Chemistry</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<pre><code class="lang-java"><span class="hljs-comment">// Mathematics teacher interface</span>

<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">MathematicsTeacher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Teacher</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Mathematics</span><span class="hljs-params">()</span></span>;

}
</code></pre>
<p>We have created different interfaces for every subject. Now <code>Jane</code> can teach English without carrying the other methods with them. Here is an example:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Jane</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">EnglishTeacher</span> </span>{

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Teach</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Jane has started teaching."</span>);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">English</span><span class="hljs-params">()</span> </span>{
        System.out.println(<span class="hljs-string">"Jane is teaching the students English language."</span>);
    }

}
</code></pre>
<h2 id="heading-dependency-inversion-principle-dip">Dependency Inversion Principle (DIP)</h2>
<p>The dependency inversion principle states:</p>
<blockquote>
<p>High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces). <em>(Source:</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Liskov_substitution_principle#:~:text=Subtype%20Requirement%3A%20Let,a%20subtype%20of%20T">Wikipedia</a><em>).</em></p>
</blockquote>
<p>And,</p>
<blockquote>
<p>Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions. <em>(Source:</em> <a target="_blank" href="https://en.wikipedia.org/wiki/Liskov_substitution_principle#:~:text=Subtype%20Requirement%3A%20Let,a%20subtype%20of%20T">Wikipedia</a><em>).</em></p>
</blockquote>
<p>Let's use a real-life example before writing some code. </p>
<p>Imagine taking a one minute walk to the bank every time you had to withdraw money over the counter. It then takes an extra thirty seconds for you get your money. This is quite efficient because very little time is wasted. We'll assume you're the high-level module and the bank is the low-level module. </p>
<p>But what happens when the bank is closed for a holiday or an emergency? You have absolutely no access to your funds. If you move further away from the bank, it becomes a bigger problem because you'd spend more time getting there.</p>
<p>To solve this problem, an interface is introduced – an automated teller machine (ATM) or a mobile banking app. Even though you have a relationship with the bank, you are no longer required to interact with them physically to be served.</p>
<p>This example is similar to the dependency inversion principle. We should make our classes rely on properties in our interfaces instead of relying on each other. </p>
<p>The implications of violating this principle would result in a rigid system where testing blocks of code independently would be very difficult, reusability of code would be near impossible, and the addition or removal of code would lead to further complexity of the system and introduce bugs.</p>
<p>Here is a code example that violates this principle:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bank</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">GIVE_CUSTOMER_MONEY_OTC</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-comment">// some logic</span>
    }
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Customer</span> </span>{
    <span class="hljs-keyword">private</span> Bank myBank = <span class="hljs-keyword">new</span> Bank();

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">withdraw</span><span class="hljs-params">()</span> </span>{
        myBank.GIVE_CUSTOMER_MONEY_OTC();
    }
}
</code></pre>
<p>From the code examples above, we can see that the <code>Customer</code> class imports and relies on a method in the <code>Bank</code> class. This reliance on a low-level class is against the DIP. </p>
<p>Like in our real-life example, we'll solve this problem by introducing an interface that both classes can interact with. </p>
<p>Here's the ATM interface that our <code>Bank</code> and <code>Customer</code> class will interact with:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ATM</span> </span>{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">ATM_OPERATION</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<p>Here's the <code>Bank</code> class which uses a method in the <code>ATM</code> interface to add money to the ATM:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Bank</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ATM</span> </span>{
    <span class="hljs-meta">@Override</span>
    ATM_OPERATION(){
        <span class="hljs-comment">// code to add money to ATM and increase the ATM balance</span>
    }
}
</code></pre>
<p>Lastly, the <code>Customer</code> class which uses the same interface to withdraw money:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Customer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">ATM</span> </span>{

    <span class="hljs-meta">@Override</span>
    ATM_OPERATION(){
        <span class="hljs-comment">// code to withdraw money from ATM and decrease the ATM balance</span>
    }
}
</code></pre>
<h2 id="heading-what-is-object-oriented-design">What Is Object Oriented Design?</h2>
<p>Object oriented design is a design methodology for building object-based systems and applications. This enables us to build systems with a collection of objects where each object has its own properties and methods.</p>
<p>Take the computer system as an example. Its hardware is made up of different parts that comprise the whole system.</p>
<p>Here are some of the general terms associated with object oriented design:</p>
<ul>
<li><strong>Objects</strong>: Each separate unit that makes up the system is an object. Objects can have properties and methods.</li>
<li><strong>Classes</strong>: Classes act as a general description for objects. So an object is an instance of a class. </li>
<li><strong>Encapsulation</strong>: this aids in bundling all the relevant data of an object in one unit. This also helps in restricting access to specific data and methods which should only be found in one object.</li>
<li><strong>Inheritance</strong>: Inheritance makes it easier for us to extend the functionality of a class to other classes.  This way, we do not repeat the process of creating these functionalities over and over again.</li>
<li><strong>Abstraction</strong>: This means showing only important attributes and hiding the irrelevant ones.</li>
<li><strong>Polymorphism</strong>: This is the existence of an interface in various forms. The ability to extend an object/interface but with different or addition attributes.</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>There are so many ways to solve a problem. But there are also many ways to create problems from a solution.</p>
<p>The more rigid and coupled the classes and methods in our code are, the more difficult it would be to maintain and reuse our code.</p>
<p>Neglecting or violating these principles could pose a serious threat to not just the codebase and the developer, but to the organization that owns the product as well.</p>
<p>A rigid and tightly coupled codebase makes it difficult to add or remove features in a product, test and reuse blocks of code, and introduces possible breaking changes with every code modification made.</p>
<p>The SOLID principles act as a guide to help us create a flexible and dynamic product and we went over each principle in this article to help us understand how the objects we create should interact which each other.</p>
<p>I hope you find this article helpful as you continue your journey through object oriented design.</p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
