Dependency Inverse Principle ( 의존 관계 역전 원칙 )
고수준 모듈, 저수준 모듈
- 고수준 모듈
- 의미 있는 단일 기능을 제공
- 상위 수준의 정책을 구현
- 저수준 모듈
- 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현
고수준 모듈, 저수준 모듈의 예시
- 기능 예 : 수정한 도면 이미지를 NAS에 저장하고 측정 정보를 DB에 저장하고 수정 의뢰 정보를 DB에 저장하는 기능
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F1e3a3bea-0613-47cc-b1f9-7b249b1ce137%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.40.03.png)
고수준 모듈이 저수준에 직접 의존하면?
- 저수준 모듈의 변경이 고수준 모듈에 영향을 줌
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F74365994-2e74-4ea7-aaa9-0e0fd0474c44%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.41.03.png)
예를 들어 고수준 모듈인 MeasureService
의 하위기능들이 위와 같이 변경되면, 정책은 변경되지 않았으나 저수준 구현 변경으로 코드의 변경이 발생하게 된다.
의존 관계 역전 원칙
- 고수준 모듈은 저수준 모듈의 구현에 의존하면 안됨
- 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야함
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F6ac16b39-d4e4-4b94-8b59-9f4720ab0a93%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.42.11.png)
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F97ab2bc8-6dec-4eb6-8af1-389dd5219b1d%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.43.39.png)
위처럼 고수준 모듈의 정책을 interface로 정의하여 구현하는 저수준 모듈들이 상속을하게 된다면, 저수준 모듈의 구현이 변경되어도 고수준 모듈의 변경이 최소화 됨.
고수준 관점에서 추상화
- 고수준 입장에서 저수준 모듈을 추상화해야함
- 구현 입장에서 추상화하지 말 것
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F02705efa-f9a4-4c3d-86e5-10e7bc08d91d%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.44.20.png)
위에서 SentryClientService
의 입장에서 추상화하게 된다면, SentryService
와 같이 추상화하게 되지만 사실 Sentry에 모아서 보고하는 것이기 때문에 고수준 모듈의 입장에서 ExceptionCollector
와 같이 추상화해야함.
DIP는 유연성을 높여준다
- 고수준 모듈의 변경을 최소화하면서, 저수준 모듈의 변경의 유연함을 높임
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F43788304-8ea9-4d44-97da-109f1bb5dc06%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.46.19.png)
이 처럼 ExceptionCollector
와 같이 추상화를 하게 되면, 저수준 모듈의 구현 변경이 있더라도 구현한 Class만 변경해주면 되기 때문에 고수준 모듈의 변경이 최소화된다.
부단한 추상화의 노력이 필요하다
- 처음부터 바로 좋은 설계가 나오지는 않는다
- 요구사항 및 업무의 이해가 높아지면서 저수준 모듈을 인지하고 상위 수준 관점에서 저수준 모듈에 대한 추상화를 시도하자
연습
- 상품 상세 정보와 추천 상품 목록 제공 기능
- 상품 번호를 이용해서 상품 DB에서 상세 정보를 구함
- Daara API를 이용해서 추천 상품 5개를 구함
- 추천 상품이 5개 미만이면 같은 분류에 속한 상품 중 최근 한달간 판매가 많은 상품을 ERP에서 구해 5개를 채움
위 요구사항을 고수준 모듈 ( 왼쪽 ) - 저수준 모듈 ( 오른쪽 ) 으로 분리하면 아래와 같다.
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2Ff9bcf3e7-1405-4fbd-96b3-2b35202d3bf4%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.49.13.png)
그리고 이것을 실제로 설계한다면 아래와 같이 설계할 수 있다.
![](https://velog.velcdn.com/images%2Fkshired%2Fpost%2F296970cc-1c1f-4c14-bbb2-477fe036ad79%2F%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-08-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.49.53.png)