The dependency injection principle states that high level code should never depend on low level interfaces, and should instead use abstractions. It’s all about decoupling code.
Not following? I don’t blame you, but it’s surprisingly simple.
Let’s say we have a piece of software that runs an online store, and within that software one of the classes (PurchaseHandler
) handles the final purchase. This class is capable of charging the user’s credit card, and does so by using a PayPal API:
The problem here is that if we change from PayPal to Square (another payment processor) in 6 months time, this code breaks. We need to go back and swap out our PayPal API calls for Square API calls. But in addition, what if the Square API wants different types of data? Or perhaps it wants us to “stage” a payment first, and then to process it once staging has completed?
That’s bad, and so we need to abstract the functionality out instead.
Rather than directly call the PayPal API from our payment page, we’ll instead create another class called PaymentHandler
. The interface for this class will remain the same no matter what underlying payment system we use, even if the two systems are completely different. We’ll still need to make changes to the PaymentHandler
interface if we change payment processor, but our higher level interface remains unchanged.
Now you may be looking at this and thinking “but wait, that’s way more code”, and you’d be right. Like many of the SOLID principles (and indeed OO principles in general), the objective is less about writing less code or writing it quicker, and more about writing better code. The above change will save you days or maybe even weeks further down the line, in exchange for spending a few hours on it now.
Top comments (0)