{"id":56,"date":"2023-09-27T14:42:22","date_gmt":"2023-09-27T14:42:22","guid":{"rendered":"https:\/\/kurtgrung.com\/blog\/?p=56"},"modified":"2024-02-06T11:58:16","modified_gmt":"2024-02-06T11:58:16","slug":"solid","status":"publish","type":"post","link":"https:\/\/kurtgrung.com\/blog\/solid\/","title":{"rendered":"SOLID"},"content":{"rendered":"\n<p><br>Today I had an interview it didn&#8217;t go well &#8230; So instead of wallowing about it I decided to proactively learn the &#8220;jargon&#8221; seeing as I already knew about Design Patterns (over 10 years ago I have read multiple books about the subject) also I have implemented them into practice depending on what I am building most of the time. So it comes naturally for me as I have been coding that long. I&#8217;ll chalk it up to the new &#8220;process&#8221; of finding a job \ud83d\ude42 <br><br>Seems like people are so caught up with Best Practices and they loose sight on what&#8217;s actually important. SHIP THE CODE. Then refactor and improve later. <\/p>\n\n\n\n<p>Implementing design patterns and practices aren&#8217;t always feasible with tight budgets &amp; deadlines on smaller projects. So unit testing isn&#8217;t even a choice in most instances. <br><br>SOLID principles provide a framework for crafting code that&#8217;s modular, easily extendable, and more manageable in the long run. Adhering to these principles supports the development of software that&#8217;s resilient, adaptable, and amenable to evolving needs.<\/p>\n\n\n\n<p>In practical applications, it&#8217;s valuable to strive for adherence to SOLID principles, but an absolute refusal to modify code can lead to detrimental outcomes in the real world. Overuse of extensive switch statements and intricate if conditions often breaches the Open-Closed principle. It&#8217;s not always feasible to strictly adhere to these principles, especially on smaller, time-critical projects.<br><br>Five design principles for writing maintainable and scalable software following the SOLID principles. These principles were introduced by Robert C. Martin &#8220;Uncle Bob&#8221; and are widely used in object-oriented programming to guide developers in creating software that is easy to understand, maintain, and extend. Each letter in the acronym &#8220;SOLID&#8221; represents one of these principles:<br><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Single Responsibility Principle (SRP):<\/strong> This principle states that a class should have only one reason to change, meaning it should have only one responsibility or job. This promotes a clean and focused design, making the class easier to understand and maintain.<br><br><strong>SRP<\/strong> uses the <strong><code>Observer<\/code><\/strong> pattern.<br><br><\/li>\n\n\n\n<li><strong>Open\/Closed Principle (OCP):<\/strong> This principle suggests that software entities (classes, modules, functions, etc.) should be open for extension but closed for modification. In other words, you should be able to extend the behavior of a class without modifying its source code.<br><br><strong>OCP<\/strong> uses: <code><strong>Strategy<\/strong><\/code> &amp; <code><strong>Decorator<\/strong><\/code> patterns.<br><br><\/li>\n\n\n\n<li><strong>Liskov Substitution Principle (LSP):<\/strong> This principle states that objects of a derived class should be able to replace objects of the base class without affecting the correctness of the program. In essence, a derived class should be substitutable for its base class.<br><br><strong>LSP<\/strong> uses the <strong><code>Factory Method<\/code><\/strong> pattern.<br><br><\/li>\n\n\n\n<li><strong>Interface Segregation Principle (ISP):<\/strong> This principle advocates for creating specific and narrow interfaces for clients, rather than having a single large interface. Clients should not be forced to depend on interfaces they do not use. This promotes decoupling and better maintainability.<br><br><strong>ISP<\/strong> uses: <code><strong>Adapter<\/strong><\/code> &amp; <code><strong>Bridge<\/strong><\/code> patterns.<br><br><\/li>\n\n\n\n<li><strong>Dependency Inversion Principle (DIP):<\/strong> This principle emphasizes high-level modules should not depend on low-level modules but both should depend on abstractions. It also states that abstractions should not depend on details; rather, details should depend on abstractions. This promotes decoupling and flexibility in the design.<br><br><strong>DIP<\/strong> uses: <strong><code>Dependency Injection<\/code> <\/strong>(DI), <strong><code>Inversion of Control<\/code> <\/strong>(IoC) container.<\/li>\n<\/ol>\n\n\n\n<p><br><br>Cheat sheet (for remembering all this): <\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Single Responsibility Principle (SRP)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Corresponding design pattern: Observer pattern.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Open\/Closed Principle (OCP)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Corresponding design patterns: Strategy pattern, Decorator pattern.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Liskov Substitution Principle (LSP)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Corresponding design pattern: Factory Method pattern.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Interface Segregation Principle (ISP)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Corresponding design patterns: Adapter pattern, Bridge pattern.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Dependency Inversion Principle (DIP)<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Corresponding design pattern: Dependency Injection (DI), Inversion of Control (IoC) container.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p><br>More about <a href=\"https:\/\/kurtgrung.com\/blog\/design-patterns\/\">Design Patterns<\/a> here. <br><br><br><strong>Code Examples<\/strong> \ud83e\udd13 <br><br><strong>Single Responsibility Principle (SRP):<\/strong><\/p>\n\n\n\n<p>SPR states that a class should have only one reason to change, meaning it should have only one responsibility or job. This principle encourages a clean and focused design where each class is responsible for a specific functionality, making the code easier to understand, maintain, and extend.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class User {\n  constructor(name, email) {\n    this.name = name;\n    this.email = email;\n  }\n\n  getName() {\n    return this.name;\n  }\n\n  getEmail() {\n    return this.email;\n  }\n}\n\nclass UserDB {\n  saveUser(user) {\n    \/\/ Logic to save the user to the database\n    console.log('User saved:', user.getName());\n  }\n\n  deleteUser(user) {\n    \/\/ Logic to delete the user from the database\n    console.log('User deleted:', user.getName());\n  }\n}\n\nconst user = new User('John Doe', 'john@example.com');\nconst userDB = new UserDB();\n\nuserDB.saveUser(user);\nuserDB.deleteUser(user);<\/code><\/pre>\n\n\n\n<p>In this example, we have two separate classes: <code>User<\/code> and <code>UserDB<\/code>. The <code>User<\/code> class is responsible for representing a user and providing methods to access user data. The <code>UserDB<\/code> class is responsible for saving and deleting users from a database.<\/p>\n\n\n\n<p>By adhering to the Single Responsibility Principle, we ensure that each class has a clear and focused purpose, making the code more maintainable and easier to reason about.<\/p>\n\n\n\n<p><br><\/p>\n\n\n\n<p><strong>Open\/Closed Principle (OCP):<\/strong><br><br>OCP is one of the SOLID principles in object-oriented programming (OOP). It was introduced by Bertrand Meyer in 1988 and is a fundamental concept for writing maintainable and extensible software.<br><br>Example. Let&#8217;s consider a scenario where we have a <code>Shape<\/code> class and we want to calculate the area of different shapes like rectangles and circles, following the OCP.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Shape {\n  area() {\n    throw new Error(\"This method should be overridden in subclasses\");\n  }\n}\n\nclass Square extends Shape {\n  constructor(side) {\n    super();\n    this.side = side;\n  }\n\n  area() {\n    return this.side * this.side;\n  }\n}\n\nclass Circle extends Shape {\n  constructor(radius) {\n    super();\n    this.radius = radius;\n  }\n\n  area() {\n    return Math.PI * this.radius * this.radius;\n  }\n}<\/code><\/pre>\n\n\n\n<p><br><br><strong>Liskov Substitution Principle (LSP):<\/strong><\/p>\n\n\n\n<p>In this example,&nbsp;<code>Duck<\/code>&nbsp;and&nbsp;<code>Penguin<\/code>&nbsp;are subclasses of&nbsp;<code>Bird<\/code>, and they can be used interchangeably with&nbsp;<code>Bird<\/code>&nbsp;without affecting the program&#8217;s correctness.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Bird {\n  fly() {\n    console.log(\"The bird is flying.\");\n  }\n}\n\nclass Duck extends Bird {\n  quack() {\n    console.log(\"Quack quack!\");\n  }\n}\n\nclass Penguin extends Bird {\n  \/\/ Penguins cannot fly, so we omit the fly method\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Interface Segregation Principle (ISP):<\/strong><br><br>In this example, we define separate interfaces for working and eating behaviors, allowing classes to implement only the behaviours they need.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Worker {\n  work() {\n    \/\/ Perform work\n  }\n}\n\nclass Eater {\n  eat() {\n    \/\/ Perform eating\n  }\n}\n\nclass RobotWorker extends Worker {\n  work() {\n    \/\/ Perform work as a robot\n  }\n}\n\nclass HumanWorker extends Worker, Eater {\n  work() {\n    \/\/ Perform work as a human\n  }\n\n  eat() {\n    \/\/ Perform eating as a human\n  }\n}<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>Dependency Inversion Principle (DIP):<\/strong><\/p>\n\n\n\n<p>In this example, the <code>UserRepository<\/code> depends on the <code>Database<\/code> abstraction rather than a specific database implementation, following the Dependency Inversion Principle.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Database {\n  save(data) {\n    \/\/ Logic to save data to the database\n  }\n}\n\nclass UserRepository {\n  constructor(database) {\n    this.database = database;\n  }\n\n  saveUser(user) {\n    this.database.save(user);\n  }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Today I had an interview it didn&#8217;t go well &#8230; So instead of wallowing about it I decided to proactively learn the &#8220;jargon&#8221; seeing as I already knew about Design Patterns (over 10 years ago I have read multiple books about the subject) also I have implemented them into practice depending on what I am [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[38,10,39,36,37,34,35,33,28,29,32,27,30,26,25,31],"class_list":["post-56","post","type-post","status-publish","format-standard","hentry","category-code","tag-dependency-inversion-principle","tag-design-patterns","tag-dip","tag-interface-segregation-principle","tag-isp","tag-liskov-substitution-principle","tag-lsp","tag-ocp","tag-oop","tag-open-closed-principles","tag-open-closed-principle","tag-principles","tag-single-responsibility-principle","tag-solid","tag-solid-principles","tag-srp"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/posts\/56","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/comments?post=56"}],"version-history":[{"count":22,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":342,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/posts\/56\/revisions\/342"}],"wp:attachment":[{"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/media?parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/categories?post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kurtgrung.com\/blog\/wp-json\/wp\/v2\/tags?post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}