Implementing DIP for Enhanced Flexibility
Understand how to implement DIP for writing code that depends on abstraction, enabling flexibility and decoupling in software design.
In this lesson, we’ll learn how the DIP allows us to split code into separate components that can change independently of each other. We’ll then see how this naturally leads to the OCP part of SOLID.
Coding for abstraction, not details
Dependency inversion (DI) means that we write code to depend on abstractions, not details.
The opposite of this is having two code blocks, one that depends on the detailed implementation of the other. Changes to one block will cause changes to another. To see what this problem looks like in practice, let’s review a counter-example. The following code snippet begins where we left off with the Shapes
class after applying SRP to it:
package shapes;import java.util.ArrayList;import java.util.List;public class Shapes {private final List<Shape> allShapes = new ArrayList<>();public void add(Shape s) {allShapes.add(s);}public void draw(Graphics g) {for (Shape s : allShapes) {switch (s.getType()) {case "textbox":var t = (TextBox) s;t.draw(g);break;case "rectangle":var r = (Rectangle) s;r.draw(g);}}}}
This code does work well to maintain a list of Shape
objects and draw them. The problem is that it knows too much about the types of shapes it is supposed to draw. The draw()
method features a switch-on-type of object that you can see. That means that if anything changes about which types of shapes should be drawn, then this code must also change. If we want to add a new Shape
to the system, ...
Get hands-on with 1400+ tech skills courses.