본문 바로가기
Framework & Library/Spring Boot

[Spring Boot] : DIP 의존 관계 역전 원칙 적용 예시

by 오주현 2022. 1. 3.
반응형
DIP 의존 관계 역전 원칙 적용 예시
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository = new MemoryMemberRepository();

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
  • MemberServiceImpl을 보면 private final MemberRepository memberRepository = new MemoryMemberRepository(); 를 통해 추상화와 구현체를 관리하고 있다.
  • 만약 요구사항 변경으로 새로운 구현체로 변경해 줘야 한다면 = new MemoryMemberRepository(); 이 부분에 대한 수정이 필요해진다.
  • MemberServiceImpl에서 추상화를 통해 구현체를 관리하고 구현체에 대한 변경이 있을 때 인터페이스를 통해서만 구현체를 변경할 수 있어야 하는데 지금 보면 인터페이스가 아닌 MemberServiceImpl에서 코드 수정이 일어난다.
  • 결국 지금 이 코드는 객체 지향 5가지 원칙 중 DIP*(Dependency Inversion Principle | 의존 관계 역전 원칙)*에 위반된다.
public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }
}
  • 해결을 위해 AppConfig 클래스를 만들어 이런 구현체들을 관리해 준다.
    • 생성과 연결을 담당한다.
  • return new MemberServiceImpl(new MemoryMemberRepository()); 코드로 구현 객체를 생성한다.
  • 간단히 해석하자면 “MemberServiceImpl을 만들고 내가 만든 MemberServiceImpl은 MemoryMemberRepository를 사용할거야.!” 와 같이 해석할 수 있다.
public class MemberServiceImpl implements MemberService {ㅗ

    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
  • public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; } 생성자를 통해 받아준다.
  • 이렇게 따로 설정 클래스에서 구현체를 받아 생성자를 통해 추상화와 구체화를 분리해 주는 것을 생성자 주입이라고 한다.
  • AppConfig 클래스에서는 결국 실제 동작에 필요한 구현 객체를 생성하게 된다.
  • AppConfig 클래스는 생성한 객체 인스턴스의 참조(레퍼런스)를 생성자를 통해 주입(연결)해준다.
  • 결국 AppConfig 객체는 객체를 생성하고 생성한 객체를 생성자로 전달하는 행위를 하게 되고 이런 행위를 DI(Dependency Injection)라고 한다.( 의존관계 주입)
  • 결과적으로는 MemberServiceImpl 클래스는 인터페이스에만 의존하게 되고 구체적인 구현 클래스에 대해 전혀 의존하지 않게 되므로 DIP를 잘 지키는 코드가 된다.
MemberService memberService;

    @BeforeEach
    public void beforEach() {
        AppConfig appConfig = new AppConfig();
        memberService = appConfig.memberService();
    }
    //MemberService memberService = new MemberServiceImpl(memberRepository);
반응형

댓글