-
Notifications
You must be signed in to change notification settings - Fork 0
SOLID: Dependency Inversion Principle (의존 역전 원칙)
DIP (의존[1] 역전 원칙)
- 상위수준에 위치한 개체는 하위수준에 위치한 개체에 의존해서는 안된다. 상위개체, 하위개체 모두 추상화에 의존해야 한다.
- 추상화는 세부 사항에 의존해서는 안된다. 세부사항이 추상화에 의존해야 한다.
장난감을 가지고 노는 아이를 만들어보겠다.

해당 다이어그램대로 코드를 짜보겠다.
public class Robot{
public String toString() {
return "로봇을 가지고 놉니다.";
}
}
public class Car{...}
public class Lego{...}
public class Kid {
private Robot robot;
private Car car;
private Lego lego;
public Kid(Robot robot, Car car, Lego lego)
{
this.robot = robot;
this.car = car;
this.lego = lego;
}
public void playRobot() {
System.out.println(robot.toString());
}
public void playCar() {
System.out.println(car.toString());
}
public void playLego() {
System.out.println(lego.toString());
}
}
public class Main{
public static void main(String[] args) {
Kid kid = new Kid(new Robot(), new Car(), new Lego());
kid.playRobot();
kid.playCar();
}
}
상위수준의 개체인 Kid클래스가 하위수준의 개체인 장난감클래스들에게 의존하고있다.🛑DIP위반
이렇게 되면, 3장난감 말고도 비행기, 기차 등 새로운 장난감이 들어올 때마다, 매번 Kid 클래스에 새로운 장난감을 선언하고, 생성자 매개변수 추가, 초기화 코드 추가까지 해주어야 한다.🛑OCP위반
그렇다면 어떻게 고쳐야 할까?

public class Robot extends Toy {
public String toString() {
return "로봇을 가지고 놉니다.";
}
}
public class Car extends Toy{...}
public class Lego extends Toy{...}
public class Kid {
private Toy toy;
// setter를 통해, 의존성 주입을 실천하였다.
public void setToy(Toy toy) {
this.toy = toy;
}
public void play() {
System.out.println(toy.toString());
}
}
public class Main{
public static void main(String[] args) {
Toy t = new Robot();
Kid k = new Kid();
k.setToy(t);
k.play();
//로봇을 가지고 놉니다.
t = new Car();
k.setToy(t);
k.play();
//자동차를 가지고 놉니다.
}
}
Toy이라는 추상 클래스 또는 인터페이스를 만들어, 장난감에 해당하는 클래스들은 Toy를 상속 받도록 만들었다.
그리고 Kid클래스는 Toy라는 추상 개체에게 의존하게 된다.
또한, Kid객체가 생성됐을 때만 초기화할 수 있었던 장난감들을, setter(.setToy(Toy toy);
)메소드를 이용해 언제, 어디서든 의존성 주입[2]을 할 수 있다.
이로써, 새로운 장난감이 생겨도 유연하게 대처할 수 있게되었다.
[1]의존이란?[↻]
누구에게 의존한다. = 스스로 할 수 없다.
∴ 누군가가 일을 대신 해주어야 한다.
public class PC {
private Game game;
private Internet internet;
public void setGame(Game game) {
this.game = game ;
}
public void setInternet(Internet internet) {
this.internet = internet;
}
public void playGame() {
game.play();
}
public void surfInternet() {
internet.surf();
}
}
해당 예제의 경우 PC는 Internet과 Game에 의존하고 있다.
[2]의존성 주입(Dependency Injection)이란?[↻]
하나의 객체가 다른 객체의 의존성을 제공하는 테크닉이다.
"의존성"은 예를 들어 서비스로 사용할 수 있는 객체이다.
클라이언트가 어떤 서비스를 사용할 것인지 지정하는 대신, 클라이언트에게 무슨 서비스를 사용할 것인지를 말해주는 것이다. 출처: 위키백과
쉽게말해
클래스가 어떤 개체에 의존할 것인지 직접 지정하는 것이 아닌,
클래스에게 어떤 개체를 의존할 것인지 말해주는 것이다.
여러 출처를 바탕으로 최대한 오류를 범하지 않도록 작성하였으나, 이 페이지를 작성하는 저 또한 해당 학문을 공부하는 학생입니다.
∴해당 페이지의 정보를 맹신하지 마시길 바랍니다.
-
생성 패턴
-
구조 패턴
- 데코레이터 패턴 (Decorator pattern)
- 어댑터 패턴 (Adapter pattern)
- 퍼사드 패턴 (Facade pattern)
- 프록시 패턴 (Proxy pattern)
- 이터레이터, 컴포지트 패턴 (Iterator, Composite pattern)
-
동작 패턴
- 옵저버 패턴 (Observer pattern)
- 템플릿 메소드 패턴 (Template pattern)
- 커맨드 패턴 (Command pattern)
- 스트래티지 패턴 (Strategy pattern)
- 스테이트 패턴 (State pattern)
-
기타 패턴
- 컴파운드 패턴 (Compound pattern)
- 메소드 체이닝 (Method chaining)
- Dispose 패턴 (Dispose pattern)