이전 포스팅을 보면 좋은 객체 지향 설계 5원칙 SOLID에서 S(SRP : 단일 책임원칙 ), L(LSP : 리스코프 치환원칙), I(ISP : 인터페이스 분리 원칙)는 지키기가 쉬웠다. 그냥 객체(클래스)에 책임을 하나만 주면 되고, 인터페이스의 구현체가 인터페이스의 책임을 무시하지 않고, 인터페이스 여러 개 만들면 되는 것이다.
문제는 O(OCP : 개방 폐쇄원칙)와 D(DIP : 의존역전원칙)에 있다.
다형성을 지켜가며 설계한다한들 구현체가 바뀌게 되면 다른 구현체에 의존하는 객체의 코드 역시 변경이 필요하다. 이 경우는 OCP위반이다. 또, 각각의 객체는 다른 객체와 협력을 해야하는데 협력을 위해 다른 구현체에 의존하는 경우 추상화(인터페이스)에만 의존하자는 DIP 원칙 위반이다.
TestInterface ti = new TestImpl(); // TestInterface 인터페이스의 구현체인 TestImpl 객체
이 때 필요한 것이 의존관계 주입(혹은 의존성 주입. DI, Dependency Injection)이다.
나 자신을 하나의
원빈객체라고 하겠다 🤚
내가 다른 객체와 협력을 하기위해 구현체를 의존해야하는데 DIP에서는 의존하지 말라고한다. 그럼 누가 대신 해줄거야? 그럼 인터페이스만 가지고 뭘 협력을 하라는거야!!!!!
맞다. 누군가 대신 해준다. 정확히 말하면 나는 인터페이스만 의존하는데 실제로는 구현체가 리턴된다.
그렇다면 나는 구현체를 직접 의존하지 않고 다른 객체랑 협력할 수 있다는 것이다. 조금만 더 쉽게 얘기하자면 협력의 상대 객체(인터페이스의 구현체)가 뭔지 누군지 전혀 모르지만 누가 됐든 나는 그 친구를 데리고 내가 할 일을 한다. 상대가 a가 됐든 b가 됐든 c가 됐든 알 바 없고 내 할 일만 하면된다. 어차피 다들 리스코프 치환원칙만 잘 지키고 있으면 내가 원하는 일 해줄 거잖아?
나는 (
원빈) 누군지도 모르는 줄리엣 역할에게 말을 걸고 세레나데를 부르고 포옹했는데 누군가가 나 몰래 줄리엣 역할에 이나영씨를 배정시켰다. 사실 나는 줄리엣이 누가 됐든 말 걸고 세레나데를 부른 뒤 포옹하면 공연을 성공적으로 마치고 칼퇴근이 가능하다.
이는 누가 대신 의존성(의존관계)을 주입해줘야만 가능한 일이다.
스프링은 이런 DI를 자동으로 혹은 수동으로 할 수 있도록 도와준다. 사실 DIP와 OCP를 지키자고 스프링을 쓰는 것은 아니다. 훨씬 더 좋은 기능들이 많이 남아있다.
OCP는 DI와도 깊은 관련이 있지만 IoC(Inversion of Control)와 조금 더 연관이 있다. 시간이 늦어 나중에 IoC를 얘기할 때 같이 설명하도록 하겠다.