기본 _ Ch.3

yuKeon·2022년 11월 7일
0

Spring_Core

목록 보기
3/8
post-thumbnail

Ch. 3 (AppConfig, DI, 스프링 컨테이너)

1. 정률 할인 정책으로 변경

public class OrderServiceImpl implements OrderService {
  //  private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
      private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
  }
  • RateDiscountPolicy() 구현체에 의존 —> DIP 위반

실제 의존관계

  • DiscountPolicy 인터페이스와 FixDiscountPolicy 구현체를 동시에 의존하고 있음

해결방안

  • OrderServiceImpl에 DiscountPolicy의 구현 객체를 외부에서 대신 주입 —> DIP
public class OrderServiceImpl implements OrderService {
      //private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
      private DiscountPolicy discountPolicy;
}

2. AppConfig

public class AppConfig {
	      public MemberService memberService() {
          return new MemberServiceImpl(new MemoryMemberRepository());
}
      public OrderService orderService() {
          return new OrderServiceImpl(
                  new MemoryMemberRepository(),
                  new FixDiscountPolicy());
} }

MemberServiceImpl - 생성자 주입

public class MemberServiceImpl implements MemberService {
        private final MemberRepository memberRepository;
        public MemberServiceImpl(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
} 
...
  • 더이상 MemberServiceImpl은 구현체(MemoryMemberRepository)에 의존하지 않는다.
  • MemberRepository(인터페이스)만 의존
  • 객체 주입은 외부(AppConfig)가 담당
  • MemberServiceImpl은 실행(find, join)만 집중

DIP 완성


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;
      }
  • MemberServiceImpl과 같은 결과(실행에만 집중, 주입은 AppConfig가 담당)

3. AppConfig 리팩토링

public class AppConfig {

      public MemberService memberService() {
          return new MemberServiceImpl(memberRepository());
			}

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

      public MemberRepository memberRepository() {
          return new MemoryMemberRepository();
			}

      public DiscountPolicy discountPolicy() {
          return new FixDiscountPolicy();
			}
	}
  • 중복 제거, 역할에 따른 구현이 잘 보이게 수정

구성, 사용 영역의 구분


DI

  • 정적인 클래스 의존관계 - 동적인 객체 의존관계 구분
  • DI를 통해 정적인 클래스 의존관계 변경 없이 동적인 객체 의존관계를 변경
  • 클라이언트 코드 변경 없이 클라이언트가 호출하는 대상의 타입 인스턴스 변경이 가능


  • 클래스 다이어그램

  • 객체 다이어그램

4. Spring으로 전환

AppConfig

@Configuration
  public class AppConfig {
      @Bean
      public MemberService memberService() {
          return new MemberServiceImpl(memberRepository());
      }
      @Bean
      public OrderService orderService() {
          return new OrderServiceImpl(
                  memberRepository(),
                  discountPolicy());
}
      @Bean
      public MemberRepository memberRepository() {
          return new MemoryMemberRepository();
      }
      @Bean
      public DiscountPolicy discountPolicy() {
          return new RateDiscountPolicy();
      }
}
  • @Configuration : 설정을 구성한다.
  • @Bean : 해당 메서드를 호출해 반환된 객체를 스프링 컨테이너에 등록, 등록된 객체가 스프링 빈

MemberApp에 스프링 컨테이너 적용

public class MemberApp {
    public static void main(String[] args) {

        //ApplicationContext == 스프링 컨테이너
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
...

OrderApp에 스프링 컨테이너 적용

public class OrderApp {
    public static void main(String[] args) {

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
  • ApplicationContext == 스프링 컨테이너

0개의 댓글