This kata complements Clean Code: SOLID, Ep. 13 - Dependency Inversion Principle.
In this exercise, you'll practice refactoring code to adhere to the Dependency Inversion Principle (DIP). You'll be working with a smart home system that controls different types of lights and an air conditioner.
The initial code consists of several device classes and the
SmartHomeController
class, which is responsible for controlling all the
devices (lights and air conditioner).
However, the initial code violates the Dependency Inversion Principle, as the
SmartHomeController
class directly depends on concrete classes. In the tests,
we also directly manipulate the dimmable_light
and networkable_light
instances to check their unique behaviors.
Your goal is to refactor the code to adhere to the Dependency Inversion Principle and make it easier to implement new devices.
Here are some guidelines to follow:
-
Introduce an interface or several interfaces (or abstract base classes) for the devices that the
SmartHomeController
interacts with. -
Update the
SmartHomeController
class to depend on this interface, instead of the concrete device classes. -
Update the devices to implement these interfaces.
-
Modify any constructors or method calls as necessary to accommodate the refactoring.
Note
Remember that in this exercise, we assume all devices are in an ideal state and don't account for error cases such as a network connection failure or an attempt to dim a light below 0% or above 100% brightness.
Make sure the program still behaves the same way after your refactoring. There's a unit test in place that checks that on a very rudimentary level by just looking at the output of the program.
When you're done with refactoring, test the quality of your refactoring by
implementing two additional scenarios (methods) in SmartHomeController
:
-
Add the
make_quick_breakfast
scenario to open the blinds and make a predefined coffee type.- Add
Blinds
device class withopen
andclose
methods (blinds are always powered and does not have on/off function). - Add
make_quick_breakfast
method toSmartHomeController
.
- Add
-
Add automatic vacuum cleaner and the
schedule_night_cleaning
scenario, which should start the cleaning once everything else is turned off.- Add
VacuumCleaner
device class withstart_cleaning
andstop_cleaning
methods. - Add
schedule_night_cleaning
method toSmartHomeController
. After calling this method, the vacuum cleaner should start cleaning once all other devices are turned off.
- Add
Evaluate whether or not your refactoring made life easier for you, or not.
You can import this project into Replit, and it will handle all dependencies automatically.
make
make run
make test