Skip to main content

Dependency Inversion Principle (DIP)

What is this?

  • This principle say:

Depend on abstractions, not implementations


Why?

  • We need to create specific interfaces instead a generic interface
  • With specific interfaces, the classes do not require useless information

Examples (JS)

Bad example

class InventoryRequester {
constructor() {
this.REQ_METHODS = ["HTTP"];
}

requestItem(item) {
// ...
}
}

class InventoryTracker {
constructor(items) {
this.items = items;

// We have created a dependency on a specific request implementation.
this.requester = new InventoryRequester();
}

requestItems() {
this.items.forEach(item => {
this.requester.requestItem(item);
});
}
}

const inventoryTracker = new InventoryTracker(["apples", "bananas"]);
inventoryTracker.requestItems();

Good example

class InventoryTracker {
constructor(items, requester) {
this.items = items;
this.requester = requester;
}

requestItems() {
this.items.forEach(item => {
this.requester.requestItem(item);
});
}
}

class InventoryRequesterV1 {
constructor() {
this.REQ_METHODS = ["HTTP"];
}

requestItem(item) {
// ...
}
}

class InventoryRequesterV2 {
constructor() {
this.REQ_METHODS = ["WS"];
}

requestItem(item) {
// ...
}
}

/* Constructing our dependencies externally and injecting them, we can easily substitute our request module for another */
const inventoryTracker = new InventoryTracker(
["apples", "bananas"],
new InventoryRequesterV2()
);
inventoryTracker.requestItems();