The dependency inversion principle is a specific form of decoupling software modules. High level modules which provide complex logic should be unaffected by the low level modules which provides utility features. To decouple high level module from low level module, we need to introduce intermediator which is protocol. The principle states:
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details. Details should depend on abstractions.
Let’s perform some transactions on user:
As part of transaction, we have to add, delete and update user in database.
Now if there is a requirement to replace current database with other database it shouldn’t affect user transaction operations. At the same time if we have to write test for these operations, it will be hard as we can’t execute tests on real database. There should be low coupling between components used. Let’s decouple this system:
DefaultUserTransactionclass conforms to
UserTransactionprotocol and uses
DataStoreprotocol to perform transaction.
- As part of this implementation, we have segregated data store from user transaction class.
For writing tests of this class,
StubDataStore can be injected.