Dependency Inversion

Classes should be provided their dependencies. Below is a trivial example of dependency inversion, using Kotlin:

1
2
3
4
5
class EmailService(private val emailClient: EmailClient) {
    fun sendEmail() {
        emailClient.send()
    }
}

This is compared to a system where class methods call external or global dependencies directly:

1
2
3
4
5
class EmailService {
    fun sendEmail() {
        EmailClient().send()
    }
}

There are a few benefits to dependency inversion. One primary benefit is that the class at hand is easier to test, because its dependencies can be mocked. Another benefit is that the calling code can substitute an EmailClient which is configured differently than the hard coded example. Finally, in terms of design, EmailService has fewer responsibilities using dependency inversion, which is always desirable.

Further Reading