{"id":791,"date":"2023-07-30T16:33:59","date_gmt":"2023-07-30T16:33:59","guid":{"rendered":"https:\/\/tbekk.com\/devstream\/?p=791"},"modified":"2023-07-30T16:41:44","modified_gmt":"2023-07-30T16:41:44","slug":"better-programming-the-interface-segregation-principle","status":"publish","type":"post","link":"https:\/\/tbekk.com\/devstream\/2023\/07\/30\/better-programming-the-interface-segregation-principle\/","title":{"rendered":"Better Programming: The Interface Segregation Principle"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-text-color has-light-gray-color has-alpha-channel-opacity has-light-gray-background-color has-background is-style-wide\"\/>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em><strong>Link: <\/strong><\/em><a href=\"https:\/\/medium.com\/@evlabs\/better-programming-the-interface-segregation-principle-7756aa0f35f3Better Programming\">The Interface Segregation Principle<\/a><\/li>\n\n\n\n<li><em><strong>Author: <\/strong><a href=\"https:\/\/medium.com\/@evlabs?source=post_page-----7756aa0f35f3--------------------------------\">Escape Velocity Labs<\/a><\/em><\/li>\n\n\n\n<li><em><strong>Publication date: <\/strong>July 30, 2023<\/em><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-text-color has-light-gray-color has-alpha-channel-opacity has-light-gray-background-color has-background is-style-wide\"\/>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/miro.medium.com\/v2\/resize:fit:1400\/1*xFXNF8AufX3SqlhvejJa7Q.png\" alt=\"\"\/><\/figure>\n\n\n\n<p id=\"443a\">In this series of articles you will become familiar with the&nbsp;<strong>SOLID principles<\/strong>, which will help you write more modular, understandable, and maintainable code. SOLID is an acronym that encompasses the following principles:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Single Responsibility Principle<\/li>\n\n\n\n<li>Open\/Closed Principle<\/li>\n\n\n\n<li>Liskov Substitution Principle<\/li>\n\n\n\n<li><strong>Interface Segregation Principle<\/strong><\/li>\n\n\n\n<li>Dependency Inversion Principle<\/li>\n<\/ul>\n\n\n\n<p id=\"897e\">In this article we will explore the fourth of these principles, called the&nbsp;<strong>Interface Segregation Principle<\/strong>. This principle states that no code should depend on functionality it does not use.<\/p>\n\n\n\n<p id=\"034e\">To learn Python and build the skills to land your first job, check out our<strong>&nbsp;<\/strong><a href=\"https:\/\/www.evlabs.io\/python-bootcamp\" rel=\"noreferrer noopener\" target=\"_blank\"><strong>Professional Python Developer Bootcamp<\/strong><\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"70cf\">How to apply the Interface Segregation Principle<\/h1>\n\n\n\n<p id=\"430d\">Let\u2019s continue with the example we saw in the&nbsp;<a href=\"https:\/\/medium.com\/@evlabs\/better-programming-the-liskov-substitution-principle-727817609b5b\">previous article<\/a>, where we implemented a music streaming application. We will be able to use this app on different types of devices: web browser, desktop application, and phone application.<\/p>\n\n\n\n<p id=\"206b\">Our app, on each of these devices, will be able to perform some functions but not others. For example, only the desktop and phone apps can download songs (and also delete downloaded songs). However, the web browser cannot do this.<\/p>\n\n\n\n<p id=\"ec85\">On the other hand, the web browser can display song lyrics in its interface (and hide them too), but the other devices cannot.<\/p>\n\n\n\n<p id=\"89f1\">One way to implement this would be to define a common interface, called&nbsp;<em>MusicPlayer<\/em>, and then, on each device create a specific player that implements those methods in an appropriate way for the platform:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from abc import ABC, abstractmethod<br><br>class MusicPlayer(ABC):<br><br>    @abstractmethod<br>    def play_song(self):<br>        pass<br><br>    @abstractmethod    <br>    def stop_song(self):<br>        pass<br><br>    @abstractmethod<br>    def download_song(self):<br>        pass<br><br>    @abstractmethod<br>    def delete_song(self):<br>        pass<br><br>    @abstractmethod<br>    def show_lyrics(self):<br>        pass<br><br>    @abstractmethod<br>    def hide_lyrics(self):<br>        pass<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">class WebPlayer(MusicPlayerInterface):<br><br>    def play_song(self):<br>        print(\"Playing song on web player\")<br><br>    def stop_song(self):<br>        print(\"Stopping song on web player\") <br><br>    def show_lyrics(self):<br>        print(\"Showing lyrics on web player\")<br><br>    def hide_lyrics(self):<br>        print(\"Hiding lyrics on web player\")<br><br>    def download_song(self):<br>        pass<br><br>    def delete_song(self):<br>        pass<br>    <br><br>class MobilePlayer(MusicPlayer):<br># Implement the appropriate methods. 'pass' on the others.<br><br>class DesktopPlayer(MusicPlayer):<br># Implement the appropriate methods. 'pass' on the others.<\/pre>\n\n\n\n<p id=\"cd6d\">However, this implementation forces your colleagues working on the different platforms to deal with code that is irrelevant to them. Additionally, as new devices emerge and you have to extend the functionality of this class, you will have to force the previous platforms to include that code as well. This makes both development and testing, as well as understanding your code, more difficult.<\/p>\n\n\n\n<p id=\"444d\">To solve this, we are going to segregate our music player interface into different smaller interfaces according to the functionality they fulfill:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">from abc import ABC, abstractmethod<br><br>class Playable(ABC):<br><br>    @abstractmethod<br>    def play_song(self):<br>        pass<br><br>    @abstractmethod    <br>    def stop_song(self):<br>        pass<br><br>class Downloadable(ABC):  <br><br>    @abstractmethod<br>    def download_song(self):<br>        pass<br><br>    @abstractmethod<br>    def delete_song(self):<br>        pass<br><br>class LyricsDisplayable(ABC):<br><br>    @abstractmethod<br>    def show_lyrics(self):<br>        pass<br><br>    @abstractmethod<br>    def hide_lyrics(self):<br>        pass<\/pre>\n\n\n\n<p id=\"b2c4\">Ahora, nuestros reproductores solo necesitan adoptar las interfaces que les son \u00fatiles, y pueden dejar las que no lo son:<\/p>\n\n\n\n<p id=\"a926\">Now, our music players only need to adopt the interfaces that are useful to them, and the can leave out the ones that are not:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class WebPlayer(Playable, LyricsDisplayable):<br><br>    def play_song(self):<br>        print(\"Playing song on web player\")<br><br>    def stop_song(self):<br>        print(\"Stopping song on web player\")<br><br>    def show_lyrics(self):<br>        print(\"Showing lyrics on web player\")<br><br>    def hide_lyrics(self):<br>        print(\"Hiding lyrics on web player\")<br><br><br>class PhonePlayer(Playable, Downloadable, Deletable):<br><br>    def play_song(self):<br>        print(\"Playing song on phone player\")<br><br>    def stop_song(self):<br>        print(\"Stopping song on phone player\")<br><br>    def download_song(self):<br>        print(\"Downloading song on phone player\")<br><br>    def delete_song(self):<br>        print(\"Deleting song on phone player\")<br><br><br>class DesktopPlayer(Playable, Downloadable, Deletable):<br><br>    def play_song(self):<br>        print(\"Playing song on desktop player\")<br><br>    def stop_song(self):<br>        print(\"Stopping song on desktop player\")<br><br>    def download_song(self):<br>        print(\"Downloading song on desktop player\")<br><br>    def delete_song(self):<br>        print(\"Deleting song on desktop player\")<\/pre>\n\n\n\n<p id=\"27f5\">If new platforms emerge with different capabilities, we can always include new interfaces and thus we will not force existing devices to adopt them.<\/p>\n\n\n\n<p id=\"828c\">Now our code is much easier to test, understand, and extend.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"b82b\">Benefits of the Interface Segregation Principle<\/h1>\n\n\n\n<p id=\"6931\">Following the Interface Segregation Principle when designing our interfaces has several benefits:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"348d\">Reduced Coupling<\/h2>\n\n\n\n<p id=\"4341\">Since classes only depend on the interfaces they actually use, your code is less entangled and more modular.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"e063\">Increased Flexibility<\/h2>\n\n\n\n<p id=\"ffd8\">Adding new, smaller interfaces to your code is easier and less error prone than modifying larger interfaces on which many parts of the code already depend.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"688f\">Increased Cohesion<\/h2>\n\n\n\n<p id=\"2e11\">Interfaces contain semantically cohesive functionality, instead of loosely related methods. This results in code that is easier to understand and contribute to.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"3a29\">Easier Testing and Maintenance<\/h2>\n\n\n\n<p id=\"4fd1\">Smaller interfaces are easier to test, and errors are easier to isolate and fix without affecting the rest of the codebase.<\/p>\n\n\n\n<p id=\"75bc\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this series of articles you will become familiar with the&nbsp;SOLID principles, which will help you write more modular, understandable, and maintainable code. SOLID is an acronym that encompasses the&#8230; <a class=\"read-more-link\" href=\"https:\/\/tbekk.com\/devstream\/2023\/07\/30\/better-programming-the-interface-segregation-principle\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,249,248,245],"tags":[74],"class_list":["post-791","post","type-post","status-publish","format-standard","hentry","category-development","category-software_architecture","category-software-development","category-solid","tag-py"],"_links":{"self":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/791","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/comments?post=791"}],"version-history":[{"count":1,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/791\/revisions"}],"predecessor-version":[{"id":792,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/posts\/791\/revisions\/792"}],"wp:attachment":[{"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/media?parent=791"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/categories?post=791"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tbekk.com\/devstream\/wp-json\/wp\/v2\/tags?post=791"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}