[05] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
핵심 내용
DI 를 하면 이렇게 좋다~ 라는 내용이 이 아이템의 핵심 내용이다. DI 의 장점에 대해서 다시 짚어보는 정도로 이해했다. 이 아이템의 요지는 'DI 를 써라' 이다.
DI 를 쓰지 않은 경우는 어떤 점이 문제일까
책에서 들고 있는 예시가 꽤 괜찮다. 코드로 구현해본다. DI 를 쓰지 않은 상황이다.
지금 핵심은 SpellChecker 가 내부적으로 Dictionary 를 만들어서 사용하고 있다는 것이다. 생성과 사용의 분리가 되어 있지 않고 클라이언트가 의존하는 것을 직접 만들어서 사용하고 있다. 만약 여기서 SpellChecker가 한국어의 스펠링까지 체크해야하는 상황이 생기면 어떻게 해야 할까?
일단 SpellChecker 는 무조건 수정을 해야한다. 인자를 바꾸든 뭘 바꾸든 수정이 들어갈 수 밖에 없다. 왜냐면 영어에 대한 체크도 유지를 해야하기 때문에 Dictionary 에 변경이 갈것이고 이 파급 효과가 당연히 클라이언트에도 갈 수 밖에 없다. KoreanDictionary 라는 것을 사용하게 하던가 Dictionary 에 추가적으로 한국어까지 체크하도록 처리를 하고 SpellChecker 에서 언어의 구분을 넣던가 해야한다.
DI 를 사용하면 무엇이 개선 되는걸까
하지만 만약 아래와 같이 SpellChecker 가 의존하는 Dictionary 를 직접 만들지 않고 주입 받아서 사용하면(= 생성과 사용의 분리를 이루고, 제어의 역전을 실현시키면) 클라이언트인 SpellChecker 는 아무런 변경을 가하지 않아도 되고 단지 주입해주는 객체만 다른 것을 넣어 주기만 하면 된다.
코드 재사용성이 좋아진다
별도의 수정 없이 지금 주입 객체를 바꿈으로써 기대하는 기능을 처리했다. 만약 SpellChecker 가 Dictionary 라는 인터페이스가 아니라 구체적 클래스에 의존하는 형태였다면 SpellChecker 를 그대로 재사용하지 못했을 것이다. 위의 케이스에는 아무 변경 없이 그대로 사용할 수 있었다.
테스트가 용이해진다
SpellChecker 를 테스트하기 위해서는 Dictionary 가 필요하다. SpellChecker 가 내부적으로 이를 사용하고 있기 때문이다.(=의존하고 있기 때문이다)
하지만 인터페이스에 의존하는 형태라면 mock 객체를 넣음으로써 SpellChecker 에만 스코프를 두고 테스트를 할 수 있다.
SRP를 더 준수할 수 있다
DI 가 적용되기 전에는 SpellChecker 가 생성의 책임까지 같이 가지고 있다. 생성과 사용 모두에 관심을 두고 있는 것이다. 하지만 주입식으로 바꾸고 나서는 SpellChecker 가 생성에는 관심을 두지 않아도 된다. 만약 위와 같이 간단한 경우가 아니라 객체를 생성하는 데 있어서 비용이 비싸다면(=전처리가 필요하다던가, 외부 api 통신을 해야한다던가 등) SpellChecker가 Dictionary를 만드는 데에도 많은 책임을 가지고 있게 되는 형태가 된다.
Last updated