Spring/스프링 핵심 원리 - 기본편

[이해2 - 객체 지향 원리 적용] 기획자 AppConfig (+ 새로운 할인 정책 적용 문제 해결)

alsruds 2023. 11. 13. 21:34
🧐강의🧐
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

 

AppConfig 등장

· AppConfig : 애플리케이션의 전체 동작 방식을 구성하기 위해, 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스

· 애플리케이션 실제 동작에 필요한 "구현 객체 생성"

          》MemberServiceImpl

          》MemoryMemberRepository

          》OrderServiceImpl

          》FixDiscountPolicy

· 생성한 객체 인스턴스의 참조를 "생성자를 통해 주입(연결)"

          》MemberServiceImpl → MemoryMemberRepository

          》OrderServiceImpl MemoryMemberRepository, FixDiscountPolicy

 

클래스 다이어그램 회원 객체 인스턴스 다이어그램

· AppConfig : 객체의 생성과 연결
· DIP 만족 : MemberServiceImpl 은 MemberRepository 추상에만 의존
· 관심사의 분리 : 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리됨

· AppConfig : memoryMemberRepository 객체 생성 & 그 참조값을 memberServiceImpl 생성 시 생성자로 전달
·DI (Dependency Injection) : memberServiceImpl 입장에서 의존 관계를 마치 외부에서 주입해주는 것 같음 

 

 

1. hello.core/AppConfig Class 생성

public class AppConfig {
    // 생성자 주입
    public MemberService memberService() {
        // ctrl + alt + m 으로 변경
        return new MemberServiceImpl(memberRepository());
    }

    private MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    private DiscountPolicy discountPolicy() {
        return new FixDiscountPolicy();
    }
}

 

2. MemberServiceImpl 코드 수정

public class MemberServiceImpl implements MemberService{
    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    ...
}

➡️ MemberRepository 인터페이스에만 의존 (DIP 만족)

 

3. OrderServiceImpl 코드 수정

public class OrderServiceImpl implements OrderService{
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

    ...
}

➡️ DiscountPolicy 인터페이스에만 의존 (DIP 만족)

 

AppConfig 실행

· AppConfig appConfig = new AppConfig()

 

1. MemberApp 코드 수정

· MemberService memberService = appConfig.memberService()

 

2. OrderApp 코드 수정

· MemberService memberService = appConfig.memberService()

· OrderService orderService = appConfig.orderService()

 

3. MemberServiceTest 코드 수정

// @BeforeEach : 각 테스트 실행 전 호출

· @BeforeEach : memberService = appConfig.memberService()

 

4. OrderServiceTest 코드 수정

· @BeforeEach

          memberService = appConfig.memberService()

          orderService = appConfig.orderService()

 

테스트 성공 !

➡️ AppConfig 를 통해 관심사를 확실히 분리

➡️ AppConfig 는 구체 클래스를 선택 : 애플리케이션이 어떻게 동작해야 할지 전체 구성 책임

 

새로운 할인 정책 적용하기

✅ AppConfig 의 등장으로 애플리케이션이 사용 영역과 구성 영역으로 분리됨

 

· AppConfig 코드 변경

public class AppConfig {
    ...
    private DiscountPolicy discountPolicy() {
        // return new FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
}

 

· 사용, 구성의 분리

기존 변경

➡️ 할인 정책을 변경해도 구성 영역에만 영향을 받고, 사용 영역에는 영향을 받지 않음