할인 정책을 애플리케이션에 적용 ---> OrderServiceImpl 코드 고침
OrderServiceImpl는 DiscountPolicy 인터페이스에 의존하면서
구체 클래스인 FixDiscountPolicy, RateDiscountPolicy이 의존 (DIP 위반)
코드를 고치면 (OCP 위반)
FixDiscountPolicy를 RateDiscountPolicy로 변경하는 순간 OrderServiceImpl의 소스도 같이 변경해야 함
AppConfig로 구현 객체 생성하고 연결하도록 만들자!!
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
public class AppConfig {
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
private MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
}
}
구현 객체 생성
MemberServiceImpl
MemoryMemberRepository
OrderServiceImpl
FixDiscountPolicy
FixDiscountPolicy->RateDiscountPolicy 객체로 변형
생성한 객체 인스턴스의 참조를 생성자를 통해서 주입
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
MemberServiceImpl -생성자 주입
package hello.core.member;
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);
}
}
MemoryMemberRepository 를 의존하지 않음
MemberRepository 인터페이스만 의존
MemberServiceImpl 입장에서 생성자를 통해 어떤 구현 객체가 들어올지 알 수 없음
오직 AppConfig에서 결정
정리
AppConfig 리팩터링
구성 정보에서 역할과 구현을 명확하게 분리
역할이 잘 드러남
중복 제거
SRP 단일 책임 원칙
- 구현 객체를 생성하고 연결하는 책임 AppConfig가 담당
DIP 의존관계 역전 원칙
- OrderServiceImpl는 DiscountPolicy 추상화 인터페이스와 FIxDiscountPolicy 구체화 구현 클래스에도 함께 의존했었다
클라이언트 코드가 DiscountPolicy 추상화 인터페이스에만 의존하도록 함
AppConfig가 FixDiscountPolicy 객체 인스턴스를 클라이언트 코드 대신 생성해서 클라이언트 코드에 의존관계를 주입
OCP
- AppConfig가 의존관계를 FixDiscountPolicy 에서 RateDiscountPolicy로 변경해서 클라이언트 코드에 주입하므로 코드는 변경 X
IoC(Inversion of Control)
-AppConfig 생성 후에는 구현 객체가 자신의 로직을 실행하는 역할만 담당
의존관계 주입 DI
정적인 클래스 의존관계
- import 코드만 보고 판단가능
동적인 클래스 의존관계
- 런타임에 외부에서 실제 구현 객체를 생성하고 클라이언트를 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라고 함
- 코드 변경없이 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있음
IoC컨테이너, DI 컨테이너
-AppConfig 처럼 객체를 생성하고 관리하면서 의존관계를 연결해주는 것
- 어샘블러, 오브젝트 팩토리 등으로 불림
'spring boot' 카테고리의 다른 글
| springboot_JPA_도메인 분석 설계 (0) | 2024.09.17 |
|---|---|
| springboot_JPA_프로젝트 환경설정 (0) | 2024.09.17 |
| 프로젝트 생성 (0) | 2024.07.23 |
| 스프링 개념 (1) | 2024.07.20 |
| 회원관리 (0) | 2024.07.04 |