DEV Community

Duncan McArdle
Duncan McArdle

Posted on

3 2

SOLID principle #5: Dependency Inversion (JavaScript)

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:

class PurchaseHandler {
processPayment(paymentDetails, amount) {
// Complicated, PayPal specific logic goes here
const paymentSuccess = PayPal.requestPayment(paymentDetails, amount);
if (paymentSuccess) {
// Do something
return true;
}
// Do something
return false;
}
}

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.

class PurchaseHandler {
processPayment(paymentDetails, amount) {
const paymentSuccess = PaymentHandler.requestPayment(
paymentDetails,
amount
);
if (paymentSuccess) {
// Do something
return true;
}
// Do something
return false;
}
}
class PaymentHandler {
requestPayment(paymentDetails, amount) {
// Complicated, PayPal specific logic goes here
return PayPal.requestPayment(paymentDetails, amount);
}
}

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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more