반응형
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);
- @BeforeEach 는 각 테스트를 실행하기 전에 무조건 실행시켜준다.
- 마지막으로 테스트 코드 또한 바꿔주고 테스트 전체 실행을 해주면
- 성공적으로 DIP 보안을 마치게 된다.
-
출처 : 스프링 핵심 원리 - 기본편 - 인프런
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard
(강의 내용을 참고로 개인 공부하여 올린 내용입니다.)
반응형
'Framework & Library > Spring Boot' 카테고리의 다른 글
[Spring Boot] : 제어의 역전 (0) | 2022.01.04 |
---|---|
[Spring Boot] : DIP 코드를 리팩터링하여 OCP도 만족하게 하기 (0) | 2022.01.04 |
[Spring Boot] : 프로젝트 설정 (0) | 2021.12.15 |
[Spring Boot] : 객체 지향과 다형성 (0) | 2021.12.15 |
[Spring Boot] : 스프링 부트와 스프링 (0) | 2021.12.15 |
댓글