SOLID Principles — Part 5

Bob Godwin
3 min readApr 27, 2018

--

Dependency Inversion Principle states that, higher level modules shouldn’t depend on the lower level modules, they should both depend on abstractions. In other words all entities should be based on Abstract Interfaces and not on Concrete Types. The principle also stressed that abstractions should not depend on details. Details should depend upon abstractions.

So the technical question here is what is a higher level module? or what can we define as a lower level module?

A High level module is any module that contains the policy decisions and business model of an application. This can be regarded as the app identity. The higher level modules are primarily consumed by the presentation layer within an app.

Low level modules are modules that contains detailed implementation that are required to execute the decisions and business policies.

Dependency Inversion Principle is sometimes mistaken for Dependency Injection. While the terms seems similar to each other, they are totally different. Dependency Injection is the process of giving an object it’s instance properties or variables. However it is difficult to talk about Dependency Inversion Principle without mentioning Dependency Injection. This is because you need Dependency Injection mechanism to realize a Dependency Inversion.

Let’s assume we want to persist, read and erase some user encoded data within our application using the “UserDefaults” with some high level abstraction that separates the actual implementation logic.

So the above code clearly defines what a “DefaultServiceType” should do.

The “UserDefaults” could be extended to provide convenience conformance of the “DefaultServiceType”.

Assuming your application is a “Game” and you want to store the player’s current state so they can resume from the same state. We could model a data structure as follows:

And extend “Game” to conformance of “Codable” protocol as shown in the implementation because we are required to have encoded user data.

Dependency Inversion Principle is actually a very sneaky concept, I hope the following explanation will clarify the concept.

Let’s write an anti-pattern usage that breaks the “Dependency Inversion Principle” by implementing our “PersistenceStore” class.

The above code is totally fine and acceptable. It is difficult to test because you have to inject explicitly a “UserDefaults” Concrete Type for your tests to work. Another thing to note is that every time you change “store” Type the “PersistenceStore” class will result into breaking changes. This is definitely not a robust code and hence the “Dependency Inversion Principle” can fix the above and make it difficult to break.

As you can see from the above implementation the code is now very easy to test, because all we need to do is to mock the “DefaultsServiceType” and we don’t have to care about the Concrete Type that implements the “DefaultsServiceType”.

This brings us to the end of our journey so far with the SOLID principles using Swift Language for practical examples, the previous principle was on Interface Segregation

For the complete playground you can find it here on the github repository.

Please feel free to reach out. I am looking forward to know what you think.

I also wrote on swift associated-type please take a look.

--

--