{"id":1519,"date":"2021-03-06T06:54:48","date_gmt":"2021-03-06T05:54:48","guid":{"rendered":"http:\/\/mateuszglowinski.pl\/?p=1519"},"modified":"2021-03-06T15:46:50","modified_gmt":"2021-03-06T14:46:50","slug":"open-closed-principle","status":"publish","type":"post","link":"https:\/\/mateuszglowinski.pl\/index.php\/2021\/03\/06\/open-closed-principle\/","title":{"rendered":"Open\/Closed Principle"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"1519\" class=\"elementor elementor-1519\" data-elementor-settings=\"[]\">\n\t\t\t\t\t\t<div class=\"elementor-inner\">\n\t\t\t\t\t\t\t<div class=\"elementor-section-wrap\">\n\t\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-b0de7ef elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"b0de7ef\" data-element_type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t\t\t<div class=\"elementor-row\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-4aa4156\" data-id=\"4aa4156\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-column-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t<div class=\"elementor-widget-wrap\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-1a02183 elementor-widget elementor-widget-text-editor\" data-id=\"1a02183\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"elementor-text-editor elementor-clearfix\"><h4>What is &#8222;Open\/Closed Principle&#8221; (OCP) ?<\/h4><p>It is the second rule of the SOLID design rules (it stands for O in SOLID <span lang=\"en\"><span data-language-for-alternatives=\"en\" data-language-to-translate-into=\"pl\" data-phrase-index=\"0\">acronym).<\/span><\/span><\/p><h4>Definition<\/h4><blockquote><div lang=\"pl-PL\" data-md=\"61\"><div role=\"heading\" data-attrid=\"wa:\/description\" aria-level=\"3\" data-hveid=\"CAoQAA\">Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.<\/div><\/div><div role=\"heading\" data-attrid=\"wa:\/description\" aria-level=\"3\" data-hveid=\"CAoQAA\">\u00a0<\/div><div lang=\"pl-PL\" data-md=\"61\"><div style=\"padding-left: 560px;\" role=\"heading\" data-attrid=\"wa:\/description\" aria-level=\"3\" data-hveid=\"CAoQAA\">\u00a0\u00a0\u00a0\u00a0 Mayer Bertrand<\/div><\/div><\/blockquote><p>It means that if user would ask for a change in the program, you as a programmer should not modify already existing classes, but you should extend existing application only by adding a new classes and functionalities.<\/p><p><span class=\"VIiyi\" lang=\"en\"><span class=\"JLqJ4b ChMk0b\" data-language-for-alternatives=\"en\" data-language-to-translate-into=\"pl\" data-phrase-index=\"0\">This goal is often achieved by dividing the system into components and preparing a hierarchy of their dependencies that would protect high-level components from changes made to low-level components.<\/span><\/span><\/p><h4>Real-life example<\/h4><p>Let&#8217;s say we have an vet application that check health of animals.<\/p><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Launcher {\n\n    public static void main(String[] args){\n        Vet vet = new Vet();\n\n        Object[] animals = {new Dog(), new Cat()};\n\n        vet.checkPetsHealth(animals);\n    }\n\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Dog {\n    public void checkHealth() {\n        System.out.println(\"Checking dog health\");\n    }\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Cat {\n    public void checkHealth() {\n        System.out.println(\"Checking cat health\");\n    }\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Vet {\n    public void checkPetsHealth(Object[] animals) {\n        for (Object animal : animals) {\n            if (animal instanceof Dog) {\n                Dog dog = (Dog) animal;\n                dog.checkHealth();\n            } else if (animal instanceof Cat) {\n                Cat cat = (Cat) animal;\n                cat.checkHealth();\n            }\n        }\n    }\n}\n<\/pre><p>UML diagram of our application:<\/p><p><img loading=\"lazy\" class=\"aligncenter\" src=\"http:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/03\/Vet-app-No-OpenClosed-Principle.png\" alt=\"\" width=\"391\" height=\"411\" \/><\/p><p>After some time out vet decided to <span lang=\"en\"><span data-language-for-alternatives=\"en\" data-language-to-translate-into=\"pl\" data-phrase-index=\"0\">expand business and check the health of hamsters as well.<\/span><\/span><\/p><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Hamster {\n    public void checkHealth() {\n        System.out.println(\"Checking hamster health\");\n    }\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Vet {\n    public void checkPetsHealth(Object[] animals) {\n        for (Object animal : animals) {\n            if (animal instanceof Dog) {\n                Dog dog = (Dog) animal;\n                dog.checkHealth();\n            } else if (animal instanceof Cat) {\n                Cat cat = (Cat) animal;\n                cat.checkHealth();\n            } else if (animal instanceof Hamster) {\n                Hamster hamster = (Hamster) animal;\n                hamster.checkHealth();\n            }\n        }\n    }\n}\n<\/pre><p>It became clear, that it is impossible to extend functionality without modifying <em>Vet<\/em> class, due to that application at this moment does not meet <em>OCP<\/em> rule.<\/p><p>Let&#8217;s refactor the code according to OCP rule. In this case, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Polymorphism_(computer_science)\" target=\"_blank\" rel=\"noopener\">polymorphism<\/a> might be helpful. We should start with adding interface for all animal &#8222;clients&#8221;.<\/p><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public interface Animal {\n    void checkHealth();\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Dog implements Animal {\n    public void checkHealth() {\n        System.out.println(\"Checking dog health\");\n    }\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Cat implements Animal {\n    public void checkHealth() {\n        System.out.println(\"Checking cat health\");\n    }\n}\n<\/pre><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Hamster implements Animal {\n    public void checkHealth() {\n        System.out.println(\"Checking hamster health\");\n    }\n}\n<\/pre><p>Thanks to that, we don&#8217;t need to check for a instance type in Vet class and therefore no modification is needed anymore in case of extending functionality.<\/p><pre style=\"background-color: lightgrey; color: black; border-radius: 5px;\">public class Vet {\n    public void checkPetsHealth(Animal[] animals) {\n        for (Animal animal : animals) {\n            animal.checkHealth();\n        }\n    }\n}\n<\/pre><p>UML diagram of our application after refactoring:<\/p><p><img loading=\"lazy\" class=\"aligncenter size-full wp-image-1651\" src=\"http:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/03\/Vet-app-with-OpenClosed-Principle.png\" alt=\"\" width=\"471\" height=\"631\" srcset=\"https:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/03\/Vet-app-with-OpenClosed-Principle.png 471w, https:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/03\/Vet-app-with-OpenClosed-Principle-224x300.png 224w, https:\/\/mateuszglowinski.pl\/wp-content\/uploads\/2021\/03\/Vet-app-with-OpenClosed-Principle-160x214.png 160w\" sizes=\"(max-width: 471px) 100vw, 471px\" \/><\/p><h4>Why should I follow &#8222;Open\/Closed Principle&#8221; ?<\/h4><p>This rule helps to maintain the code, which is easy to extend and friendly for new features.<\/p><\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>What is &#8222;Open\/Closed Principle&#8221; (OCP) ? It is the second rule of the SOLID design rules (it stands for O in SOLID acronym). Definition Software&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[34],"tags":[35],"_links":{"self":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1519"}],"collection":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/comments?post=1519"}],"version-history":[{"count":73,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1519\/revisions"}],"predecessor-version":[{"id":1778,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/posts\/1519\/revisions\/1778"}],"wp:attachment":[{"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/media?parent=1519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/categories?post=1519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mateuszglowinski.pl\/index.php\/wp-json\/wp\/v2\/tags?post=1519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}