어떤 객체에서 다른 클래스를 의존하고자 할 때 구상 클래스에 의존하지 말고 인터페이스와 같이 추상화 된 것에 의존하라는 법칙이다. DIP에서 의존성은 객체간에 의존성을 말한다.
💡의존성 역전 원칙
1. 상위 모듈은 하위 모듈에 의존하면 안된다. 상위 모듈 하위 모듈은 모두 추상화에 의존해야 한다.
2. 추상화는 세부사항에 의존하면 안된다. 세부사항이 추상화에 의존해야 한다.
출처: 위키 피디아
abstract class Renderer {
constructor() {}
_render() {
throw "override method!";
}
render() {
this._render();
}
}
class TableRenderer extends Renderer {
constructor() {
super();
}
_render() {
console.log("table render!");
}
}
class ConsoleRender extends Renderer {
constructor() {
super();
}
_render() {
console.log("console render!");
}
}
class App {
renderer: Renderer;
constructor(renderer: Renderer) {
this.renderer = renderer;
}
render() {
this.renderer.render();
}
}
const app = new App(new TableRenderer());
const app2 = new App(new ConsoleRender());
app.render();
app2.render();
어떤 데이터를 받아 render하는 클래스를 만들었다. Renderer
클래스를 추상 클래스로 만들고 이를 구현한 클래스 TableRenderer
와 ConsoleRenderer
를 만들었다. 위 코드는 DIP를 만족한다. App
클래스가 구상 클래스인 TableRenderer
나 ConsoleRenderer
에 의존하는 것이 아니라 Renderer
클래스에 의존하게 하고 내부 구현은 각 클래스의 _render()
메소드를 오버라이딩하여 구현하도록 했다.
render의 결정을 런타임 시점으로 옮길 수 있게 되어, 조금 더 유연한 코드를 작성할 수 있게 되었다. 새로운 렌더러가 필요하다면 Renderer클래스를 구현한 클래스를 만들면 해결할 수 있게 되었다.(OCP 만족)
참고
- 코드스피츠