의존성 주입은 프로그램 디자인이 결합도를 느슨하게 한다.
의존성 주입은 의존관계 역전 원칙과 단일 책임 원칙을 따르도록 한다.
클라이언트의 객체 생성에 대한 의존성을 클라이언트의 행위로부터 분리하는 것이다.
의존성 주입은 다음과 같은 문제를 해결한다.
객체를 필요로하는 클래스 내에서 직접 객체를 생성하는 것은 클래스를 특정 객체에 커밋하는 것이다.
이후에 클래스로부터 독립적으로(클래스의 수정 없이) 인스턴스의 생성을 변경하는 것이 불가능하기 때문에 유연하지 못하다.
이는 다른 객체를 필요로하는 경우 클래스를 재사용할 수 없게한다.
또한 실제 객체를 모의 객체로 대체할 수 없기 때문에 클래스를 테스트하기 힘들게한다.
// 변경 전
public class MemberServiceImpl implements MemberService {
MemberRepository memberRepository = new JdbcMemberRepository();
@Override
public void join(Member member) {
memberRepository.save(member);
}
}
// 변경 후
public class MemberServiceImpl implements MemberService {
MemberRepository memberRepository = new JpaMemberRepository(); // 여기가 변경됨
@Override
public void join(Member member) {
memberRepository.save(member);
}
}
위 코드는 객체지향 설계 원칙에 어긋나는 코드다.
객체지향 설계 원칙 중 SRP, OCP, DIP에 위반한 상황이다.
SRP 단일 책임 원칙
(Single Responsibility Principle)OCP 개방-폐쇄원칙
(Open/Closed Principle)DIP 의존관계 역전 원칙
(Dependency Inversion Principle)MemberRepository memberRepository = new JdbcMemberRepository();
MemberRepository memberRepository = new JpaMemberRepository();
new JdbcMemberRepository() -> new JpaMemberRepository()
다음과 같이 바꾸어 의존성 주입을 활용한다.
인터페이스만 의존하도록 설계를 변경해야한다.
public class MemberServiceImpl implements MemberService {
MemberRepository memberRepository;
@Override
public void join(Member member) {
memberRepository.save(member);
}
}
참고