CHALLENGE THREE: DEPENDENCY INVERSION PRINCIPLE AND RETROFACTORING
CODE FOR THIS CHALLENGE (ZIP'D ECLIPSE PROJECT) AVAILABLE HERE.
The following are stated in Martin’s (2002, p. 127) discussion of the Dependency Inversion Principle (DIP).
a. "High-level modules should not depend on low-level modules. Both should depend on abstractions."
b. "Abstractions should not depend on details. Details should depend on abstractions."
The following schematics are recreations of figures from Martin (2002)
The problem with this configuration is that changing things in a lower layer, such as the Utility Layer can break things in the Mechanism Layer. Then Martin presents a preferred configuration.
With the use of this configuration, Martin (2002, p. 129) states:
"Using this inversion of ownership, PolicyLayer is unaffected by any changes to MechanismLayer or UtilityLayer. Moreover, PolicyLayer can be reused in any context that defines lower-level modules that conform to the PolicyServiceInterface. Thus, by inverting the dependencies, we have created a structure, which is simultaneously more flexible, durable and mobile."
A more specific example is then presented when the discussion includes a switch controlling a lamp as shown in the shematic below.
Martin offers the following preferred configuration with inverted dependency.
When preparing materials for my students, I often take refactored code and retrofactor it back to a point where they can then refactor it. In this challenge, I experienced an “ahah moment” when I was retrofactoring it and thought it might be useful to have the students try the same thing. The code I have provided has already been refactored to implement the dependency inversion principle (DIP). The schematic below shows the refactored configuration.
The student should remove the interface and configure the lamp (LightBulb or Fan) so that it is tightly coupled with the switch (SwitchPanel). To get the application to work, students should be aware of what must be done in terms of visibility/accessibility to establish the dependency?