DIP (Dependency Inversion Principle; 의존 역전 법칙)

프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.". DI(의존성 주입) 역시 이 원칙을 따르는 방법 중에 하나이다.

 

 

 


구현체에 의존

 

 

 

메인 화면과 메모 상세 화면에서 메모 데이터를 조작하고 싶다.

그래서 MainPresenter와 MemoDetailPresenter는 MemoLocalRepository를 가지고 있다.

 

로컬 데이터베이스(임베디드 데이터베이스)를 사용하여 앱을 만드려한다.

MemoLocalRepository는 *RoomDatabase에서 메모 데이터를 받아오도록 작성했다.

*RoomDatabase : Android 임베디드 데이터베이스

 

 

 

개발도중 서버를 사용하는 것으로 요구사항이 변경되었다.

 

이로 인해 MemoLocalRepository를 고쳐야했고 이를 사용중이던 MainPresenter와 MemoDetailPresenter 역시 수정이 필요했다. (의존성)

 

 

 

 


DIP 적용

 

 

위와 같은 일을 막기 위해 구조부터 변경했다.

MemoRepository를 인터페이스로 만들었다.

 

MemoLocalRepository는 MemoRepository 인터페이스상속받아 만들었고

MainPresenter와 MemoDetailPresenter는 MemoRepository 인터페이스로 가지고 있다.

 

사용하는 부분에서도 구현하는 부분에서도 추상화에만 의존하고 있다.

 

이로 인해 MainPresenter와 MemoDetailPresenter는

어디서 어떻게 받아오는지 상관없이 인터페이스 함수대로 데이터를 조작할 수 있다.

 

MemoLocalRepository 대신 MemoRemoteRepository로 변경하던 MemoDummyRepository로

변경하던 상관없이 MemoRepository에만 의존성을 가지고 있으면 된다.

 

 

 

 

 


DI

 

MemoPresenter는 MemoRepsotiroy 인터페이스에만 의존하면 된다.

그럼 MemoRepository는 어디서 어떻게 생성해주지?

 

어디선가 MemoLocalRespository를 생성해서 전달해준다면 

그 생성한 클래스는 결국 구현체에 의존하게 되는데 조삼모사가 아닌가?

 

그래서 DI가 존재한다.

 

전문적으로 생성해서 전달해주는 모듈이 있고

구현체를 몰라도 모듈에 설정한대로 외부에서 구현체를 생성해 전달해주어

사용하는 부분은 구현체에 의존성없이 사용할 수 있다.

 

class MainPresenter(
    private val memoRepository: MemoRepository
)

private val presenter: MainPresenter by inject()

 

위와 같은 코드 형태이다.

by inject()를 통해 외부에서 인스턴스를 만들어 준다.

 

어떤 구현체의 인스턴스인지 명시하지 않고 사용할 수 있어 의존성이 전혀 없다. 

 

DI 역시 DIP의 방법 중에 하나이고

DI를 통해 DIP를 더 잘 지킬 수 있다.

 

 

 

 

 


외부 포스팅

 

좋은 DIP 포스팅

https://medium.com/@lightsoo/dependency-inversion-principle-52a7bb6dd6be

 

Dependency Inversion Principle

본부장님의 클린코드 강의중 Function Structure를 공부하면서 DIP에 대한 설명을 듣는데 이해가 잘 되지않아서 다시 위의 내용을 번역 + DIP강의를 듣고 정리한 문서이다.

medium.com

 

 

 

'SoftwareDesign' 카테고리의 다른 글

ISP  (0) 2020.03.01
LSP  (0) 2020.03.01
OCP  (0) 2020.03.01
SRP  (0) 2020.03.01
SOLID 개요  (0) 2020.03.01

+ Recent posts