Backend/Spring

[섹션 3] AppConfig과 생성자 주입

지미닝 2024. 3. 18. 20:43

본 게시물은 김영한 선생님의 강의를 학습하며 작성하였습니다.

관심사의 분리

디카프리오는 어떤 여자 주인공이 선택되더라도 똑같이 공연할 수 있어야 한다.

AppConfig의 등장

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

import com.hello.core.discount.FixDiscountPolicy;
import com.hello.core.member.MemberService;
import com.hello.core.member.MemberServiceImpl;
import com.hello.core.member.MemoryMemberRepository;
import com.hello.core.order.OrderService;
import com.hello.core.order.OrderServiceImpl;

public class AppConfig {
    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }

    public OrderService orderService() {
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
    }
}
  • 실제 동작에 필요한 구현 객체를 생성한다
  • 생성한 객체 인스턴스의 참조를 생성자를 통해서 주입한다

클래스 다이어그램

  • 객체의 생성과 연결은 AppConfig가 담당한다.
  • DIP 완성: MemberServiceImplMemberRepository인 추상에만 의존하면 된다. → 구체 클래스는 몰라도 된다!
  • 관심사의 분리: 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리되었다.

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

  • appConfig객체는 memoryMemberRepository객체를 생성하고 그 참조 값을 memberServiceImpl를 생성하면서 생성자를 전달한다.
  • 클라이언트인 memberServiceImpl 입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 DI(Dependency Injection) 우리말로 의존관계 주입 또는 의존성 주입이라고 한다.

AppConfig 리팩터링

package com.hello.core;

import com.hello.core.discount.DiscountPolicy;
import com.hello.core.discount.FixDiscountPolicy;
import com.hello.core.discount.RateDiscountPolicy;
import com.hello.core.member.MemberRepository;
import com.hello.core.member.MemberService;
import com.hello.core.member.MemberServiceImpl;
import com.hello.core.member.MemoryMemberRepository;
import com.hello.core.order.OrderService;
import com.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 FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
}