SOLID Design Principles

Abdullah Aimen
2 min readApr 12, 2019
Building a wall in the right way retains its strength

In the previous article, we talked about the fourth Principle of SOLID Principles series. we demonstrated an example to make everything clear and obvious.

Today, we are going to talk about the last principle…

Dependency Inversion Principle (DIP)

It’s a specific form of decoupling software modules.

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.

Which means, high- and lower-level layers reduce the traditional dependencies from top to bottom.

At some point of development for your projects, the app will be largely composed of classes and modules. When this happens we should be prepared for that complexity.

The following image discuss the implementation of DIP

Before and After applying DIP model

In this version of DIP, the lower layer component’s dependency on the interfaces/abstracts in the higher-level layers makes re-utilization of the lower layer components difficult. This implementation instead ″inverts″ the traditional dependency from top-to-bottom to the opposite, from bottom-to-top.

So, How we can apply the DIP?

if we follow Figure 1 structure so the implementation will be like…

class DataAccessLayer {
fun retrieveData(key: String): String {
return "the value of $key is random"
}
}
class BusinessLogicLayer {
private var mDataAccessLayer: DataAccessLayer

init {
mDataAccessLayer = DataAccessLayer()
}

fun retrieveData(key: String) {

System.out.println(mDataAccessLayer.retrieveData(key))
}
}

And the implementation…

fun main(array: Array<String>) {
var mBusinessLogicLayer = BusinessLogicLayer()
mBusinessLogicLayer.retrieveData("key0")
}

When applying DIP it becomes...

interface IRepository {
fun retrieveData(key: String):String
}

class BusinessLogicLayer(var mIRepository: IRepository) {

fun retrieveData(key: String): String {
return mIRepository.retrieveData(key)
}
}

fun main(args: Array<String>) {
var mIRepository = DataAccessLayer()
var mBusinessLogicLayer = BusinessLogicLayer(mIRepository)
System.out.println(mBusinessLogicLayer.retrieveData("key0"))
}

as we saw how easy the implementation will be and the re-usability of the logic layer to be injected in any module. The outcome is that the BusinessLogicLayer class does not depend on lower level modules, but rather abstractions. Also, low-level modules and their details depend on abstractions.

# Conclusion

“If you take the SOLID principles to their extremes, you arrive at something that makes Functional Programming look quite attractive” — Mark Seemann

Following SOLID Concepts becomes the minimum requirement for developing a maintainable, well-organized and extensible code which reflects somehow in the performance of the software overall.

Remember always you are a Programmer, not Plumper! Thanks for continuing the article. If you like it just clap and share!

References

Object-Oriented Programming

SOLID Principles

--

--