<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Naomi Dennis</title>
    <description>The latest articles on DEV Community by Naomi Dennis (@naomidennis).</description>
    <link>https://dev.to/naomidennis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F74080%2F0b096fea-ae92-48ce-86b6-0da813bdcf63.jpg</url>
      <title>DEV Community: Naomi Dennis</title>
      <link>https://dev.to/naomidennis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/naomidennis"/>
    <language>en</language>
    <item>
      <title>Favorite Refactoring Techniques: Extract Class</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Thu, 16 Jan 2020 20:58:12 +0000</pubDate>
      <link>https://dev.to/naomidennis/favorite-refactoring-techniques-extract-class-i2e</link>
      <guid>https://dev.to/naomidennis/favorite-refactoring-techniques-extract-class-i2e</guid>
      <description>&lt;p&gt;The next refactoring technique we'll look at is extracting classes. Extracting classes has a similar thought process as extracting functions. In both cases, we are extracting behavior. For classes however, we are extracting &lt;em&gt;sets&lt;/em&gt; of behavior or data. &lt;/p&gt;

&lt;p&gt;Say we have the following code: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Multiple conditionals that test strings is a perfect code smell that indicates something can be refactored. In this situation, each string in the &lt;code&gt;if statement&lt;/code&gt; denotes a name for an item in a shop. The body of each statement is the same; it performs a transaction with said item, the item's value and the money of the person shopping. After the transaction is complete, &lt;code&gt;#perform_transaction()&lt;/code&gt; returns the amount of money the shopper has left. The only clause that is different is &lt;code&gt;else&lt;/code&gt;, which outputs a message to the shopper that the requested item is not found. &lt;/p&gt;

&lt;p&gt;With this information we can split the behavior of the conditionals into two parts: performing a transaction when the item is in the shop and outputting a message when the item is not in the shop. Looking at the transaction portion, we can see that each item not only has its own name, but its own value. We can extract this into a &lt;code&gt;ShopItem&lt;/code&gt; class. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With this class, we can rewrite our if statement to more accurately portray the first portion, checking if the item is in the shop and outputting a message if it isn't. Before extracting the class, if the item wasn't apart of the conditional statement, it was seen as not being included in the shop. Now, we can create a list of items and if the item isn't in the list, we can output the message. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;Now our code tells a concrete story. Search for an item. If the item is found, perform the transaction and return money to the shopper, if the item isn't found then tell the shopper the item isn't being sold. &lt;/p&gt;

&lt;p&gt;As it stands, our if statement looks pretty good. However, we can make some minor changes to make it a bit better. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;All in all, our code now looks this (Please note, &lt;code&gt;# -- snip --&lt;/code&gt; is code that wasn't mentioned.) : &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>extractclass</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Favorite Refactoring Techniques: Extract Functions</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Thu, 09 Jan 2020 20:21:12 +0000</pubDate>
      <link>https://dev.to/naomidennis/favorite-refactoring-techniques-extract-functions-i39</link>
      <guid>https://dev.to/naomidennis/favorite-refactoring-techniques-extract-functions-i39</guid>
      <description>&lt;p&gt;The next refactoring technique we'll look at is extracting behavior into functions. Say we have the following example: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;SubwayTrain#processStop&lt;/code&gt; has a lot of behavior. The intention could be made clearer by separating each behavior into its own method. The behavior we extract will also become available to other classes that may need it, outside of the context of getting passengers at a subway station. &lt;/p&gt;

&lt;p&gt;After extracting the behavior, &lt;code&gt;#processStop&lt;/code&gt; looks like this: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>extractfunction</category>
      <category>refactoring</category>
    </item>
    <item>
      <title>Favorite Refactoring Techniques: Combine Functions Into Transform</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Thu, 02 Jan 2020 13:51:23 +0000</pubDate>
      <link>https://dev.to/naomidennis/favorite-refactoring-techniques-combine-functions-into-transform-266</link>
      <guid>https://dev.to/naomidennis/favorite-refactoring-techniques-combine-functions-into-transform-266</guid>
      <description>&lt;p&gt;When multiple functions have related behavior that acts on an object together, they can combine into a single function to transform an object. Behavior is the main way to determine of multiple functions should be combined. Let's look at an example. &lt;/p&gt;

&lt;p&gt;Say, we have the following functions that calculates the total price at a restaurant. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The calculation functions all relate to determining the total. Because we would need to call &lt;code&gt;calculateDiscount&lt;/code&gt; whenever we call &lt;code&gt;calculateSalesTax&lt;/code&gt; or &lt;code&gt;calculateTip&lt;/code&gt; to get an accurate total; we should consolidate these calls into a single function. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Another way of determining the relationship between functions, is to look at its input, output and name. All calculate functions accept a number and return a number. Based on the semantic meaning of calculating the discount, sales tax and tip, we can determine these methods will likely, &lt;em&gt;only&lt;/em&gt;, be called together. After this, we can peek into the functions and get a better idea of its behavior. In our example, each calculation function is returning a changed price.&lt;/p&gt;

&lt;p&gt;Thus, we create a brand new function that combines all calculations and returns a &lt;em&gt;transformed&lt;/em&gt; price. &lt;/p&gt;

</description>
      <category>combinefunctions</category>
      <category>refactoring</category>
    </item>
    <item>
      <title> Favorite Refactoring Techniques: Split Phase</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Thu, 26 Dec 2019 16:36:16 +0000</pubDate>
      <link>https://dev.to/naomidennis/favorite-refactoring-techniques-split-phase-1bbj</link>
      <guid>https://dev.to/naomidennis/favorite-refactoring-techniques-split-phase-1bbj</guid>
      <description>&lt;p&gt;Split phase is the technique of breaking down and separating bloated behavior. Say we have a function that has multiple behaviors or a single line of code that carries out several behaviors and it's hard to deduce the result. We would &lt;em&gt;split&lt;/em&gt; the different &lt;em&gt;phases&lt;/em&gt; of a program's instruction; rather than keeping them altogether to make it more understandable and readable. &lt;/p&gt;

&lt;p&gt;In the example below, the purpose of the program is to board passengers.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We can identify four behaviors in this script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parse input from user&lt;/li&gt;
&lt;li&gt;Separate passengers based on class&lt;/li&gt;
&lt;li&gt;Board the passengers in order of class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To begin refactoring, we are going to separate the behaviors into functions.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In summary we split the instructions in &lt;code&gt;rawPassengerData#map&lt;/code&gt; into the following functions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#processPassengers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#separatePassengerIntoFlightClass&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#boardPassengers&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#checkAllPassengersBoarded&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;code&gt;#main()&lt;/code&gt; was added to give the program a proper starting point to call main instructions. If we were to read the instructions in &lt;code&gt;#main()&lt;/code&gt;, we can deduce the program will: processes a list of raw passenger data, board passengers and checks that all passengers were boarded. All without needing to know the inner workings of each function.&lt;/p&gt;

&lt;h1&gt;
  
  
  In Conclusion
&lt;/h1&gt;

&lt;p&gt;A good way to view the split phase technique is to keep your functions small, readable and consisting of one behavior. There is more we can do like creating classes and streamlining passenger creation. Look out for future blog posts on refactoring to see the techniques used! &lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>splitphase</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Package Cohesion: Reuse-Release Equivalence Principle</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Tue, 10 Dec 2019 17:36:34 +0000</pubDate>
      <link>https://dev.to/naomidennis/package-cohesion-reuse-release-equivalence-principle-3d28</link>
      <guid>https://dev.to/naomidennis/package-cohesion-reuse-release-equivalence-principle-3d28</guid>
      <description>&lt;p&gt;Package cohesion is a way of composing packages that makes them reusable and easily maintainable. There are three package cohesion principles, reuse-release equivalence, package common reuse and common closure. &lt;/p&gt;

&lt;p&gt;Let's look at the reuse-release equivalence principle. &lt;/p&gt;

&lt;p&gt;REP states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The granule of reuse is the granule of release &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, I prefer the longer definition of: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All classes in a package must be reusable, and all packages must be released via bug tracking, version control and other forms of release. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A good example of this is the &lt;code&gt;io&lt;/code&gt; package in Java. It's a package that is easily usable in complex input/output situations. All classes in the &lt;code&gt;io&lt;/code&gt; package depend on either default types or types included in itself. &lt;/p&gt;

&lt;p&gt;For example, we would only include classes from the &lt;code&gt;io&lt;/code&gt; package if we used &lt;code&gt;ByteArrayOutputStream&lt;/code&gt; or &lt;code&gt;IOException&lt;/code&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;An example of a package breaking the REP, is if the package needs other packages to be used. Take the example below: &lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@Naomi_Dennis/example1?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;p&gt;Exploring the files menu, we can see that the the Player package is dependent on the Armor and Weapon packages, limiting its reusability. The Armor and Weapon packages are &lt;em&gt;more&lt;/em&gt; reusable since it does't depend on other packages. Like the Math package, a reusable package should be useable in a different project. If the Player package was exported to a different project, it wouldn't be usable since the Armor and Weapon packages are not defined. &lt;/p&gt;

&lt;p&gt;We can fix this by combining the classes into one GameObjects package. &lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@Naomi_Dennis/repexamplerefactor?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  In Conclusion
&lt;/h3&gt;

&lt;p&gt;The reuse-release equivalence principle is great for ensuring that packages can be used across multiple projects. One major benefit of this principle is a single package can be used across multiple versions of a project since all changes are inclusive. &lt;/p&gt;

&lt;p&gt;One thing we didn't talk about is releasing a package. That largely depends on the developers as there are many different bug tracking, version control, documentation tools, support tools, etc. that are available and it's largely based on preference. The gist of the idea, is, as packages are created and made reusable they should be released to the wider project and/or public. &lt;/p&gt;

</description>
      <category>packageprinciples</category>
      <category>reusereleaseequivalence</category>
      <category>package</category>
      <category>cohesion</category>
    </item>
    <item>
      <title>A Light Introduction Liskov Substitution Principle </title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Fri, 06 Dec 2019 15:12:25 +0000</pubDate>
      <link>https://dev.to/naomidennis/a-light-introduction-liskov-substitution-principle-295a</link>
      <guid>https://dev.to/naomidennis/a-light-introduction-liskov-substitution-principle-295a</guid>
      <description>&lt;p&gt;The Liskov substitution principle, is the &lt;strong&gt;L&lt;/strong&gt; in SOLID principles. It was created by Barbara Liskov and states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Subtypes must be able to substitute base types. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aside from the obvious implementation of this principle -- ensuring the subtype has the same behavior as the base type -- the implicit implementation is ensuring the subtype has the same &lt;em&gt;semantic&lt;/em&gt; behavior as the base type. &lt;/p&gt;

&lt;p&gt;Semantic is defined as: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Relating to meaning in language or logic.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And so, we create a definition of what the class name means. Typically, squares and rectangles are defined through their mathematic definition. Mathematically, a square is a shape with four sides in equal lengths. For rectangles, we will be using the definition of a perfect rectangle, meaning a shape where the top and bottom sides have equal lengths and left and right sides have equal lengths. &lt;/p&gt;

&lt;p&gt;From this definition, we can conclude that a square's width and height must be the same while a rectangle can have a width different from its height as well as having a width equal to its height. &lt;/p&gt;

&lt;p&gt;Let's create classes for these shapes, where we just define the width and height. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We can see that a &lt;code&gt;Square&lt;/code&gt; object can easily replace a &lt;code&gt;Rectangle&lt;/code&gt; object in a given situation. All &lt;code&gt;Square&lt;/code&gt; objects share the same behavior as &lt;code&gt;Rectangle&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;However, we can see the semantic difference, when we test &lt;code&gt;#area()&lt;/code&gt;. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;Because a rectangle can have a different height than its width the result of &lt;code&gt;#area()&lt;/code&gt; adheres to our semantic definition. &lt;/p&gt;

&lt;p&gt;If we replaced &lt;code&gt;Rectangle&lt;/code&gt; with &lt;code&gt;Square&lt;/code&gt; the test will pass, but the &lt;code&gt;Square&lt;/code&gt; object is no longer behaving the way we expect. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Because a square's width and height cannot be different, the &lt;code&gt;Square&lt;/code&gt; object breaks our semantic definition. This breaks the Liskov substitute principle.&lt;/p&gt;

&lt;p&gt;The easiest way to ensure both &lt;code&gt;Rectangle&lt;/code&gt; and &lt;code&gt;Square&lt;/code&gt; pass the test, while satisfying LSP, is to remove line 4.  &lt;/p&gt;

&lt;p&gt;You may be thinking, why not implement a &lt;code&gt;#setWidth()&lt;/code&gt; function in &lt;code&gt;Rectangle&lt;/code&gt; that can be overwritten in &lt;code&gt;Square&lt;/code&gt;? This would cause &lt;code&gt;Square&lt;/code&gt; to only share the interface of &lt;code&gt;Rectangle&lt;/code&gt; instead of its behavior, making the abstraction unnecessary. By removing line 4, we can satisfy LSP and we can go even further by making &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; private. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  In Conclusion
&lt;/h3&gt;

&lt;p&gt;When implementing inheritance, be sure to adhere to the meaning of the class outside of the implementation. This helps the class become more understandable in the grand scheme of the project.&lt;/p&gt;

&lt;p&gt;Another technique that helps ensure classes adhere to LSP is &lt;a href="http://www.cs.unc.edu/~stotts/145/CRC/DesByContract.html"&gt;design by contract&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>lsp</category>
      <category>java</category>
      <category>liskovsubstitutionprinciple</category>
    </item>
    <item>
      <title>Open / Closed Principle</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Tue, 26 Nov 2019 15:19:36 +0000</pubDate>
      <link>https://dev.to/naomidennis/open-closed-principle-nbb</link>
      <guid>https://dev.to/naomidennis/open-closed-principle-nbb</guid>
      <description>&lt;p&gt;The open closed principle is the &lt;strong&gt;O&lt;/strong&gt; in the SOLID principles. It was created by Bertrand Meyer and states: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Software entities should be open for extension, but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's dive deeper with an example. &lt;/p&gt;

&lt;p&gt;We've been tasked with creating a platform that merges all video streaming sites. The platform will be able to add a platform to its list of platforms, search for a video on all platforms and play a video from the search results. The class can look like so: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;CentralVideoStreamingPlatform&lt;/code&gt; covers most mainstream video streaming platforms. However, if we were to add another platform, say &lt;code&gt;DisneyPlus&lt;/code&gt;, another &lt;code&gt;#add()&lt;/code&gt; would be created. This directly violates the open for extension aspect of OCP.&lt;code&gt;CentralVideoStreamingPlatform&lt;/code&gt; must be open to accept different details without needing to change code that's already written. By overloading &lt;code&gt;#add()&lt;/code&gt; &lt;em&gt;again&lt;/em&gt;, we are needlessly changing &lt;code&gt;CentralVideoStreamingPlatform&lt;/code&gt;. Who's to say how many &lt;code&gt;#add()&lt;/code&gt; &lt;code&gt;CentralVideoStreamingPlatform&lt;/code&gt; would have as more streaming platforms are added? &lt;/p&gt;

&lt;p&gt;To ensure &lt;code&gt;CentralVideoStreamingPlatform&lt;/code&gt;'s extensibility, we can refactor the video streaming classes to implement a &lt;code&gt;VideoStreamingPlatform&lt;/code&gt; interface and use one &lt;code&gt;#add()&lt;/code&gt;. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  In Conclusion
&lt;/h3&gt;

&lt;p&gt;The open closed principle is a great principle to keep in mind when writing classes.  &lt;/p&gt;

</description>
      <category>solid</category>
      <category>java</category>
      <category>ocp</category>
    </item>
    <item>
      <title>Single Responsibility Principle</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Thu, 21 Nov 2019 11:42:07 +0000</pubDate>
      <link>https://dev.to/naomidennis/single-responsibility-principle-3n58</link>
      <guid>https://dev.to/naomidennis/single-responsibility-principle-3n58</guid>
      <description>&lt;p&gt;The first concept in SOLID principles is the single responsibility principle. According to Robert Martin's Agile Software Development: Principles, Patterns and Practices, it is defined as: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A class should have only one reason to change &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The definition is simple enough, but let's look at an example to really solidify its meaning. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Despite the class looking relatively simple, there is actually a lot going on. &lt;code&gt;Game&lt;/code&gt; controls how the board is rendered, how the player's turn is carried out, if a winner is found and the main game loop. If the way the board is rendered changes, &lt;code&gt;#renderBoard()&lt;/code&gt; will have to change. If the rules of the game changes how a player should conduct their turn, &lt;code&gt;#playerTurn()&lt;/code&gt; and possibly &lt;code&gt;#detectWinner()&lt;/code&gt; will have to change. If we decided to create a more complicated game, where an Ai or some other high level action has to happen, &lt;code&gt;#start()&lt;/code&gt; would have to change. &lt;/p&gt;

&lt;p&gt;The easiest way to separate responsibility is to separate the functions into classes depending how on they change in respect to one another. &lt;code&gt;#renderBoard()&lt;/code&gt; can be separated into its own class, because changing how the board is rendered doesn't necessitate changing the game's loop or the game's rules. It only cares about the medium the board is rendered on; for example, a phone app or command line. &lt;code&gt;#playerTurn()&lt;/code&gt; and &lt;code&gt;#detectWinner()&lt;/code&gt; can be separated from &lt;code&gt;Game&lt;/code&gt;, but kept together. The rules of the game dictates how the player conducts their turn and how a player wins. If the rules of the game changes, both &lt;code&gt;#detectWinner()&lt;/code&gt; and &lt;code&gt;#playerTurn()&lt;/code&gt; changes. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;With these changes, the only behavior left in &lt;code&gt;Game&lt;/code&gt; is the main game loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Conclusion
&lt;/h3&gt;

&lt;p&gt;When determining how to separate responsibility, look for what Robert Martin calls, "an axis of change". For example, if &lt;code&gt;#detectWinner()&lt;/code&gt; and &lt;code&gt;#startPlayerTurn()&lt;/code&gt; behavior weren't related, we could segregate &lt;code&gt;#detectWinner()&lt;/code&gt; into its own class. However, for our example, this is unnecessary. Be sure not to introduce needless complexity. &lt;/p&gt;

</description>
      <category>solid</category>
      <category>java</category>
      <category>singleresponsibilityprinciple</category>
    </item>
    <item>
      <title>Dependency Inversion Principle</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Mon, 18 Nov 2019 16:20:07 +0000</pubDate>
      <link>https://dev.to/naomidennis/dependency-inversion-principle-1kbj</link>
      <guid>https://dev.to/naomidennis/dependency-inversion-principle-1kbj</guid>
      <description>&lt;p&gt;The last SOLID rule is the dependency inversion principle. According to Robert Martin's Agile Software Development: Principles, Patterns and Practices, the principle is defined as,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1) High level modules shall not depend on low-level modules. Both shall depend on abstractions.&lt;/p&gt;

&lt;p&gt;2) Abstractions shall not depend on details. Details shall depend on abstraction &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a lot, so let's look at each rule separately.&lt;/p&gt;

&lt;h2&gt;
  
  
  High Level Modules Shall not Depend on Low-Level Modules
&lt;/h2&gt;

&lt;p&gt;Let's look at a very simple Java example: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this example, &lt;code&gt;Monitor&lt;/code&gt; is dependent on &lt;code&gt;DisplayPortCable&lt;/code&gt; and &lt;code&gt;DisplayPortCable&lt;/code&gt; is dependent on &lt;code&gt;Laptop&lt;/code&gt;. If &lt;code&gt;Monitor&lt;/code&gt; wants to use a different cord, say an &lt;code&gt;HDMI&lt;/code&gt; or &lt;code&gt;VGA&lt;/code&gt; cord, we will be forced to change &lt;code&gt;Monitor&lt;/code&gt; directly. We &lt;em&gt;could&lt;/em&gt; give &lt;code&gt;Monitor&lt;/code&gt; multiple constructors for each cord type; we could also create a base class that holds the behavior for all the cords. However, these approaches aren't desirable as it leaves the class rigid and cumbersome to expand and it could become bloated.  A base class may seem like a good idea, but it's too tempting to add behavior for all the cords in one place and simply extend it to the newly created classes. This bloat tends to break the &lt;a href="https://dev.to/naomidennis/introduction-to-the-interface-separation-principle-3bmj"&gt;interface segregation&lt;/a&gt; principle. The same holds true for the relationship between &lt;code&gt;DisplayPortCable&lt;/code&gt; and &lt;code&gt;Laptop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In statically typed languages like Java, it's best to invert the dependency using an interface (or virtual classes in C++). Interfaces allows us to define a low level type for our higher level classes (like &lt;code&gt;Monitor&lt;/code&gt;) to use. &lt;/p&gt;

&lt;h4&gt;
  
  
  Inverting a Dependency
&lt;/h4&gt;

&lt;p&gt;When inverting a dependency, we want the classes that are being depended on (in our example &lt;code&gt;DisplayPortCable&lt;/code&gt; and &lt;code&gt;Laptop&lt;/code&gt;) to instead, depend on an interface. Continuing with our example, the relationship between &lt;code&gt;DisplayPortCable&lt;/code&gt; and &lt;code&gt;Monitor&lt;/code&gt; looks like so:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;From the example, we create an interface for &lt;code&gt;VideoCable&lt;/code&gt; and implement the cable we plan on using for &lt;code&gt;Monitor&lt;/code&gt;. Instead of &lt;code&gt;Monitor&lt;/code&gt; being restricted to accepting &lt;code&gt;DisplayPortCable&lt;/code&gt; it can now accept any &lt;code&gt;VideoCable&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;There is still a dependency in our code because &lt;code&gt;VideoCable&lt;/code&gt; is dependent on &lt;code&gt;Laptop&lt;/code&gt;. This helps brings us to the next part of this principle. &lt;/p&gt;

&lt;h2&gt;
  
  
  Abstractions Shall not Depend on Details. Details Shall Depend on Abstraction
&lt;/h2&gt;

&lt;p&gt;When thinking about the details of a class, I like to think that details mean the behavior and properties of a class. In our example, this means &lt;code&gt;#connect()&lt;/code&gt; and &lt;code&gt;#connectedDevice&lt;/code&gt;. Although our &lt;code&gt;DisplayPortCable&lt;/code&gt; is abstracted, it's still dependent on &lt;code&gt;Laptop&lt;/code&gt;. The question we ask is the same that we asked before. What if a &lt;code&gt;VideoCable&lt;/code&gt; wanted to connect to a &lt;code&gt;Desktop&lt;/code&gt; or a &lt;code&gt;Smartphone&lt;/code&gt; instead of a &lt;code&gt;Laptop&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;And so, we invert the dependency like we did before. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Dynamic vs Static Approaches to Dependency Inversion
&lt;/h3&gt;

&lt;p&gt;The example above was done in Java. Statically typed languages usually have a concrete way of defining abstract interfaces. However, in dynamically typed languages, the idea of an abstract class is harder to implement as the tools to do so are not typically a feature of the language. In cases like this, we can use a technique known as duck typing. &lt;/p&gt;

&lt;p&gt;Duck typing is the idea, that if the behavior of a class walks in a particular way, and talks in a particular way, that way can be abstracted to the dependent classes.&lt;/p&gt;

&lt;p&gt;The difference between an interface-esque keyword approach to dependency inversion and duck typing, is the former is written in contract form where the behavior is explicitly defined and enforced; the latter is not explicitly defined and becomes apparent as more object types are used within a class. If we were to convert our above code to Ruby, duck typing wouldn't be obvious because there's only one object type depending on an abstraction. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The issue becomes more apparent as we add more classes. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since there isn't a defined contract, we &lt;em&gt;could&lt;/em&gt; use any old interface with our new classes and simply ask for the type of &lt;code&gt;videoConnector&lt;/code&gt; and use whatever interface was defined. However, this not only makes &lt;code&gt;Monitor&lt;/code&gt; difficult to extend (since we'd have to manually add a new conditional to understand a new type), but it leads &lt;code&gt;Monitor&lt;/code&gt; to know about the inner workings of other classes which directly violates this principle. &lt;code&gt;Monitor&lt;/code&gt; has to depend on an abstraction of the object it's receiving. &lt;code&gt;Monitor&lt;/code&gt; shouldn't care about the object's class, just its behavior. &lt;/p&gt;

&lt;p&gt;To do this, we have to consciously ensure the classes have an agreed upon interface and that they depend on this interface. In the case of our example, we have to dictate if &lt;code&gt;#connectToDevice()&lt;/code&gt; will expect &lt;code&gt;videoConnector&lt;/code&gt; to have the &lt;code&gt;#connect()&lt;/code&gt; or &lt;code&gt;#connectToSomething()&lt;/code&gt; behavior. &lt;/p&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;Dependency inversion can be tricky. However, it allows a class to be more flexible and trains us to think about classes in terms of behavior, rather than construction. &lt;/p&gt;

</description>
      <category>solid</category>
      <category>java</category>
      <category>ruby</category>
      <category>softwaredesign</category>
    </item>
    <item>
      <title>Introduction to the Interface Segregation Principle</title>
      <dc:creator>Naomi Dennis</dc:creator>
      <pubDate>Fri, 15 Nov 2019 19:33:06 +0000</pubDate>
      <link>https://dev.to/naomidennis/introduction-to-the-interface-separation-principle-3bmj</link>
      <guid>https://dev.to/naomidennis/introduction-to-the-interface-separation-principle-3bmj</guid>
      <description>&lt;p&gt;The interface segregation principle is the &lt;strong&gt;I&lt;/strong&gt; in SOLID principles. According Robert Martin's Agile Software Development: Principles, Patterns and Practices, the principle is defined as, “Clients should not be forced to depend on methods that they do not use.” In other words, classes should not have access to behavior it does not use. Let’s look at a Python example. &lt;/p&gt;

&lt;p&gt;We’ve been hired to create a game where the player sets up entertainment systems. Each piece of the system (television, dvd player, game console, etc.) uses a specific cord to connect to another device. We know that a TV uses an HDMI cord to connect to a game console, and a dvd player uses RCA cords to connect to a TV. Both the game console and TV connects to a router via an ethernet cord so they can access the internet. And lastly, all the devices are connected to the wall via a power cord so they can turn on.&lt;/p&gt;

&lt;p&gt;Say we create a class to handle all the connections listed above.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EntertainmentDevice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaRCACord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; 
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectDeviceToPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, all we have to do is extend this interface to our device classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Television&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntertainmentDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToDVD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dvdPlayer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaRCACord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dvdPlayer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToGameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plugInPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectDeviceToPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DvdPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntertainmentDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plugInPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectDeviceToPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntertainmentDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plugInPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectDeviceToPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EntertainmentDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToGameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plugInPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectDeviceToPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Looking at each class, you’ll notice that every class only uses a method or two from &lt;code&gt;EntertainmentSystemDevice&lt;/code&gt;. For instance, &lt;code&gt;DVDPlayer&lt;/code&gt; only uses &lt;code&gt;#connectToTV&lt;/code&gt; and &lt;code&gt;#connectToPowerOutlet&lt;/code&gt; methods. There’s also a bit of duplication across the classes. Each class uses &lt;code&gt;#connectToPowerOutlet&lt;/code&gt;. First, let’s work on separating the &lt;code&gt;EntertainmentSystemDevice&lt;/code&gt; interface. &lt;/p&gt;

&lt;p&gt;We can extract &lt;code&gt;#connectToDeviceViaEthernetCord&lt;/code&gt; and create a class dedicated to internet devices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InternetDevice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both HDMI and RCA cords are used for transmitting audio and video data. The difference between the two, is RCA handles analog signals, while HDMI handles digital signals. We can use this difference to create two classes, &lt;code&gt;AnalogDevice&lt;/code&gt;, and &lt;code&gt;DigitalDevice&lt;/code&gt; that handles devices connected by RCA and HDMI respectively.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnalogDevice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaRCACord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; 

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DigitalDevice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;EntertainmentSystemDevice&lt;/code&gt; class now only has the &lt;code&gt;#connectToPowerOutlet&lt;/code&gt; method. Because it only handles behavior for connecting a device to an outlet, the class name should change to reflect that. We can also define a &lt;code&gt;#plugInPower&lt;/code&gt; method that uses the &lt;code&gt;#connectDeviceToPowerOutlet&lt;/code&gt; method. Let’s rename &lt;code&gt;EntertainmentSystemDevice&lt;/code&gt; to &lt;code&gt;WallPoweredDevice&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WallPoweredDevice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plugInPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__connectToDeviceViaPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__connectToDeviceViaPowerOutlet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our classes are looking pretty good.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Television&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WallPoweredDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InternetDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AnalogDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DigitalDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToDVD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dvdPlayer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaRCACord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dvdPlayer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToGameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DvdPlayer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WallPoweredDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AnalogDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaRCACord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WallPoweredDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InternetDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DigitalDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaHDMICord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WallPoweredDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InternetDevice&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToTV&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;television&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connectToGameConsole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gameConsole&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end, we were able to refactor our device interfaces to only have access to behavior it uses. Because the behavior is separated based on the sole behavior the class supports, the extended classes act as a description of the subclass. For example, we know that a router uses the internet and needs to be plugged into the wall without having to look at the inner functionality of the class.&lt;/p&gt;

&lt;p&gt;We can take this idea one step further and say, classes should only use objects where it uses the entire interface of said object. This is a bit difficult to show in a dynamically typed language like Python, so we will convert our &lt;code&gt;Router&lt;/code&gt; class to Java and convert our &lt;code&gt;InternetDevice&lt;/code&gt; class to a Java interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;InternetDevice&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InternetDevice&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;WallPoweredDevice&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;InternetDevice&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;connectToDeviceViaEthernetCord&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InternetDevice&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="o"&gt;){}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;Router&lt;/code&gt; can only connect to another device that uses the internet. Because we want it to &lt;em&gt;only&lt;/em&gt; have access to behavior associated with an &lt;code&gt;InternetDevice&lt;/code&gt;, we tell it to only understand objects that use the &lt;code&gt;InternetDevice&lt;/code&gt; interface. &lt;/p&gt;

&lt;p&gt;This way, even if we implement an &lt;code&gt;InternetDevice&lt;/code&gt; to other classes like &lt;code&gt;Television&lt;/code&gt; or &lt;code&gt;GameConsole&lt;/code&gt;, Router's &lt;code&gt;#connectToDeviceViaEthernetCord&lt;/code&gt; will only have access to the functions associated with &lt;code&gt;InternetDevice&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;To learn more about Java interfaces, follow the link &lt;a href="https://www.tutorialspoint.com/java/java_interfaces.htm"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;When adding additional features to the program, such as connecting to the internet not only via ethernet, but also via Wi-Fi, be sure to pay attention to the cohesion of the methods. How well do the methods relate to each other? If a class were given the set of behavior defined in the base class or acknowledged in an interface, would the class actually need the behavior? By answering these questions we are able to create reusable, general classes that are easier to delegate. &lt;/p&gt;

&lt;p&gt;Gists: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/Naomi-Dennis/5936da7c366bc85801931567a704a2a8"&gt;Example code before refactoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/Naomi-Dennis/1ae5634dd19ac1f07ada5b5a5ecb83e4"&gt;Example code after refactoring&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/Naomi-Dennis/1f74e334ea3bda11b69dd35d0a8b9515"&gt;Example code for Java example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>solid</category>
      <category>python</category>
      <category>java</category>
    </item>
  </channel>
</rss>
