shreyansh

Dependency Inversion Principle

DI principle: Don't depend on concrete implementation, rather depend on abstraction.

MouseKeyboardInterfacesWiredMouseBluetoothMouseWiredKeyboardBluetoothKeyboardchild classes of the interface, Mouse and Keyboard.

NOT Following DIP Principle 🚫

class MacBook{
	private final WiredKeyboard keyboard;
	private final WiredMouse mouse;

	public Macbook(){
		keyboard = new WiredKeyboard();
		mouse = new WiredMouse();
	}
}

The MacBook class directly creates instances of WiredKeyboard and WiredMouse classes. This creates a tight coupling between MacBook and these specific implementations which can't be changed in future.

Following DIP Principle βœ…

class MacBook{
	private final Keyboard keyboard;
	private final Mouse mouse;
	
	public MacBook(Keyboard keyboard, Mouse mouse){
		this.keyboard = keyboard;
		this.mouse = mouse;
	}
}

In this code, MacBook specifications can be modified. Keyboard and Mouse can be of either wired or bluetooth or any other type for that matter and therefore, MacBook class isn't tightly coupled with KeyBoard and Mouse as these are INTERFACE and not CONCRETE CLASSES.

The MacBook class now depends on abstractions (Keyboard and Mouse) instead of concrete implementations. This allows you to easily swap out different implementations of keyboards and mice without modifying the MacBook class. The high-level module (MacBook) and low-level modules (WiredKeyboard, WiredMouse) are both dependent on abstractions, which follows the Dependency Inversion Principle.