7 부록, DIP 소개

source: categories/study/oop_programming/opp_programming_7.md

7. DIP

  • 객체 지향 프로그래밍을 학습한 후, 이어 학습하면 좋을 거 같은 내용인 DIP를 부록에 담았습니다.

고수준 모듈, 저수준 모듈

  • 고수준 모듈
    • 의미 있는 단일 기능을 제공하는 모듈을 고수준 모듈이라고 함
    • 고수준 모듈은 상위 수준의 정책 구현함
  • 저수준 모듈
    • 고수준 모듈의 기능을 구현하기 위해 필요한 하위 기능의 실제 구현한 모듈을 저수준 모듈이라고 함

고수준 모듈, 저수준 모듈 예

  • 기능 예:
    • 수정한 도면 이미지를 NAS에 저장하고
    • 측정 정보를 DB 테이블에 저장하고
    • 수정 의뢰 정보를 DB에 저장하는 기능
고수준 저수준
도면 이미지를 저장하고 NAS에 이미지를 저장한다
측정 정보를 저장하고 MEAS_INFO 테이블에 저장한다
도면 수정 의뢰를 한다 BP_MOD_REQ 테이블에 저장한다
  • 도면 이미지를 저장하는 고수준의 하위 기능을 구현한 저수준 모듈은 NAS에 이미지를 저장한다 이다.
  • 측정 정보를 저장하는 고수준의 하위 기능을 구현한 저수준 모듈은 MEAS_INFO 테이블에 저장한다 이다.

  • 이렇게 고수준 모듈은 기능의 정책을 제공하고
  • 저수준 모듈은 하위 기능의 구현을 제공한다.

고수준이 저수준에 직접 의존하면

  • 그런데 고수준이 저수준에 직접 의존하면 어떻게 될까요?

  • 저수준 모듈 변경 -> 고수준 모듈에 영향
  • 아래에 보시는 코드처럼 MeasureService가 고수준 모듈인데, 이 모듈에서 도면 이미지 저장에 해당하는 하위 기능에 대해
  • NAS에 저장한다는 저수준 모듈을 바로 사용했다고 가정해봅시다.


public class MeasureService {
    public void measure(MeasureReq rea) {
        File file = req.getFile();
        nasStorage.save(file);

        jdbcTemplate.update("insert into MEAS_INFO ...");

        jdbcTemplate.update("insert into BP_MOD_REQ ...");
    }
}


  • 위 코드를 수정하면..
  • 위 상태에서 도면 이미지를 NAS말고 아마존 s3에 저장하도록 저수준 모듈이 바뀌게되면,
  • MeasureService 모듈이 아래 코드처럼 바뀌게 됩니다.


public class MeasureService {
    public void measure(MeasureReq rea) {
        File file = req.getFile();
        s3storage.upload(file);

        jdbcTemplate.update("insert into MEAS_INFO ...");

        rabitmq.convertAndSend(...);
    }
}


  • 고수준 정책이 바뀌지 않았으나 저수준 구현 변경으로 코드 변경 발생

DEPENDENCY INVERSION PRINCIPLE

  • 이렇게 고수준 모듈이 저수준 모듈에 의존하면서 발생하는 문제,
  • 즉, 저수준 구현이 바뀌면서 고수준 모듈도 같이 바뀌는 문제를 방지하기 위한 원칙이 바로 DIP (DEPENDENCY INVERSION PRINCIPLE) 의존 역전 원칙이다.
  • 고수준 모듈이 저수준 모듈에 의존하면 안되며
  • 저수준 모듈이 고수준 모듈에서 정의한 추상타입에 의존해야 한다는 것이 DIP이다.

  • 의존 역전 원칙
    • 고수준 모듈은 저수준 모듈의 구현에 의존하면 안됨
    • 저수준 모듈이 고수준 모듈에서 정의한 추상타입에 의존해야 함

고수준 관점에서 추상화

  • DIP에서 하위 기능에 대한 추상 타입을 도출할 때에는 고수준 입장에서 추상화 해야합니다.
  • 저수준 입장에서 추상화하면 안된다.

  • 고수준 입장에서 저수준 모듈을 추상화
    • 구현 입장에서 추상화하지 말 것

DIP는 유연함을 높임

  • 고수준 모듈의 변경을 최소화하면서 저수준 모듈의 변경 유연함을 높임

부단한 추상화 노력 필요

  • 처음부터 바로 좋은 설계가 나오지는 않음
    • 요구사항/업무 이해가 높아지면서 저수준 모듈임을 인지하고 상위 수준 관점에서 저수준 모듈에 대한 추상화 시도

  • 익셉션이 발생하면 Sentry에 익셉션 정보를 보냄 -> 익셉션이 발생하면 Sentry에 익셉션 정보를 모음 -> 익셉션이 발생하면 익셉션을 모음

연습

  • 상품 상세 정보와 추천 상품 목록 제공 기능
    • 상품 번호를 이용해서 상품 DB에서 상세 정보를 구함
    • Daara API를 이용해서 추천 상품 5개 구함
    • 추천 상품이 5개 미만이면 같은 분류에 속한 상품 중 최근 한달 판매가 많은 상품을 ERP에서 구해서 5개를 채움

연습 - 고수준 / 저수준 분류

  • 상품 번호를 이용해서 상품 DB에서 상세 정보를 구함
  • 추천 엔진 Daara API를 이용해서 추천 상품 5개 구함
  • 추천 상품이 5개 미만이면 같은 분류에 속한 상품에서 최근 한 달 판매가 많은 상품을 구해서 5개를 채움
고수준 모듈에 해당하는 하위 기능 고수준 각 하위 모듈에 해당하는 저수준 구현
상품 번호로 상품 상세 정보 구함 DB에서 상세 정보 구함
추천 상품 5개 구함 Daara API에서 상품 5개 구함
인기 상품 구함 같은 분류에 속한 상품에서 최근 한달 판매가 많은 상품 ERP에서 구함

  • DIP만 잘해도 좋은 설계가 될 확률이 매우 높아진다.
  • 여러분도 고수준과 저수준 관점에서 기능을 분리하고 설계하는 연습을 많이 해보시면 좋은 설계를 얻는데 큰 도움이 될 것입니다.