Skip to main content

Dependency Inversion Principle (DIP)

The Dependency Inversion Principle (DIP) is a principle of object-oriented design that states that high-level modules should not depend on low-level modules, but rather both should depend on abstractions. This means that instead of directly depending on concrete implementations of classes, modules should depend on abstract interfaces or contracts. This allows for better code organization and maintainability, as well as flexibility to accommodate future changes in requirements. To implement the DIP, developers can use techniques such as abstraction, inversion of control, and dependency injection.

Explain Dependency Inversion Principle (DIP) like I'm five

The Dependency Inversion Principle is like a toy robot. A toy robot can do different things, like walk and talk and dance. And even though the robot can do all these different things, it doesn't have to do them all by itself. Instead, it can use other things to help it do the things it wants to do. For example, the robot might use batteries to make it move, and a speaker to make it talk. And even though the robot is using batteries and a speaker, it doesn't have to know how the batteries and the speaker work. It just has to know what they can do for it. In object-oriented programming, the toy robot is like a high-level module, and the batteries and the speaker are like low-level modules. The Dependency Inversion Principle says that high-level modules should use low-level modules without knowing how they work, so that the high-level modules can be more flexible and reusable.

Code examples

class User
def send_email
email_client = EmailClient.new
email_client.send_email(to: 'user@example.com', subject: 'Hello', body: 'Hello, how are you?')
end
end

class EmailClient
def send_email(to:, subject:, body:)
# Send the email using a third-party email service
end
end

In this example, the User class depends on the EmailClient class to send emails. This creates a tight coupling between the two classes, because the User class is directly dependent on the EmailClient class for its functionality.

This violates the Dependency Inversion Principle because it means that any changes to the EmailClient class will also affect the User class. For example, if the EmailClient class changes the way it sends emails, the User class will also be affected.

A better design would be to invert the dependency between the two classes by introducing an abstraction between them. For example, you could create an EmailService interface with a send_email method, and have the EmailClient class implement this interface. The User class could then depend on the EmailService interface, rather than the concrete EmailClient class. This would allow you to change the implementation of the email service without affecting the User class.