본문 바로가기
IT 공부/공부하며 알게된 사실들

DIP(의존성 역전 원칙)에 대해 지금까지 잘못 알고 있었던 것 같다.

by exdus3156 2023. 10. 19.

1. DIP와 자바 인터페이스의 의미.

  • DIP란 의존성 역전 원칙(Dependancy Inversion Principle)을 이르는 영어 표현이다. 여기서 의존성이란 소스 코드에 대한 의존성을 말한다.
  • 의존성이 객체지향에서 중요하게 다뤄지는 이유는 한 모듈이 다른 모듈에 의존할 때 변경의 여파가 발생하기 때문이다. 사용하는 모듈A가 사용되는 모듈B에 의존한다. 이때 모듈B의 내용이 변경되면 그것을 사용하는 모듈A도 변경되어야 한다는 압박을 받게 된다.
  • 또 다른 SOLID 원칙 중 하나인 OCP(개방 폐쇄 원칙)는 이러한 의존성의 방향을 일관적으로 관리하는 원칙을 말한다. 우리가 시스템을 여러 모듈과 컴포넌트, 클래스로 분리한 이상 이들이 서로를 의존하는 것은 절대 막을 수 없다. 의존성이 나쁜 것이 아니라, 의존성이 관리되지 않을 때 나쁜 것이다. OCP는 확장에는 열려 있고 변경에는 닫혀 있어야 한다고 말한다. 만약 변경의 여파로부터 보호하고 싶은 모듈(변경에 닫혀 있도록 하고 싶은 모듈)이 있다면, 그 모듈은 너무 많은 다른 모듈에 의존하면 안 될 것이다.
  • 따라서 이 모듈은 외부로 향하는 의존성의 방향을 자기 자신 쪽으로 돌려야 한다. 여기서 자바의 인터페이스가 유용하게 사용된다.
  • A모듈이 B 모듈의 특정 메소드에 의존하고 있다고 해보자. 하지만 설계자는 이 방향을 바꾸고 싶다. 더 중요한 로직을 담고 있는 A모듈을 B모듈로부터 보호하고 싶은 것이다. 이때 A 모듈 내부에 인터페이스를 둘 수 있다. 그러면 A모듈은 더 이상 B모듈의 특정 메소드에 의존하지 않는다. 대신 인터페이스의 코드에 의존한다.
  • B모듈은 이전에는 메소드를 만들어 놓고, A모듈이 그것을 호출한 관계였다. 그러나 중간에 인터페이스를 둠으로써 그 관계가 역전되었다. 이제 B모듈이 A모듈의 인터페이스를 지켜야 한다. 여기가 중요하다. 이전에는 A모듈에서 B모듈로 의존성 화살표가 날아갔다. 그러나 이제는 B모듈이 A모듈의 인터페이스를 향해 의존성의 방향을 날린다. 이 때문에 의존성이 역전되었다고 표현하는 것이다.

 

2. 내가 잘못 알고 있었던 점

  • 나는 자바의 인터페이스의 배후에 이런 개념적 원리가 숨어 있는 줄을 몰랐다. 겉으로는 SOLID 원칙을 달달 외웠으나 제대로 이해하지 못했다. 그저 인터페이스를 C언어의 함수 선언문 정도로 파악했던 것이다.
  • 많은 책과 강의를 보고, 구글링을 해서 인터페이스의 사용법과 그 의미를 추적해왔었다. 그러나 기껏해야 얻은 지식이라곤 "클래스간 결합력이 약해진다"는 정도의 깨달음였다. 이 말 자체가 무슨 말인지는 이해했다. 그러나 왜 결합력이 중요하게 다뤄지는지 몰랐다. SOLID의 여러 원칙에서 언급되는 응집력, 결합력 등의 개념들과 뒤죽박죽 섞이면서 더 혼란스러웠다.
  • 인터페이스는 메소드의 포맷을 지정하는 것인데, 굳이 따지면 C언어의 함수 선언문(헤더 파일에 있는 코드들)과 다를 것이 없어 보였다. 그리고 중요한 것은 자바는 클래스의 메소드를 구체적으로 명시한다고 해도, 사용되는 클래스가 그 메소드의 포맷만 지킨다면 수정을 해도 사용하는 클래스의 재컴파일 없이도 잘 작동한다는 것이었다. 이 점이 혼란스러웠다. "그렇다면 굳이 인터페이스라는 녀석을 만들 이유가 있나?" 싶었다.
  • 하지만 최근에서야 자바의 인터페이스가 단순히 포맷에 대한 약속 문서 정도에 그치는 것이 아니라, 아키텍처 상에서 의존성 역전(DI)를 통해 의존성의 방향을 관리하여 불필요한 순환 의존, 혹은 잦은 변경으로부터 모듈을 보호하는 역할을 한다는 것을 깨달았다.