개발이 좋아서/Spring이 좋아서
DI (Dependency Injection) / IoC (Inversion of Control) 예제로 알아보자
zoaseo
2024. 12. 27. 19:08
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
- MemberServiceImpl은 지금 MemberRepository(추상) 뿐만 아니라 MemoryMemberRepository(구체/구현)에도 의존하고 있다. 그렇기 때문에 DIP원칙을 위반하는 것이다.
- 그리고 구현체를 일일이 저기서 바꿔끼워줘야 하기때문에 OCP원칙도 위반이 된다.
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
private MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
- appConfig를 만들어 관심사를 분리했다. 외부에서 주입을 하게끔 만들었다.
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
- 그래서 MemberServiceImpl에서 MemberRepository(구체/구현)에만 의존하게 되어 DIP원칙을 지킬 수 있다.
이것을 의존성 주입(Dependency Injection)이라고 한다.
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
private MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
private DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
- appConfig 안에서 FixDiscountPolicy에서 RateDiscountPolicy로 변경만 해주면 된다.
- 프로그램에 대한 권한은 모두 appConfig가 가지고 있다. 그런 사실도 모른체 MemberServiceImpl은 묵묵히 자신의 로직을 실행하고 있다. 이렇듯 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전(IoC)이라 한다.
- appConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해 주는 것을 IoC 컨테이너 또는 "DI 컨테이너"라고 한다.