[spring기본]3. 스프링 핵심 원리 이해 2 - 객체 지향 원리 적용(관심사의 분리)

이건회·2022년 8월 27일
0

springbasic

목록 보기
3/14
  • 이제 이전 프로젝트에서 기획자가 새로운 할인 정책을 추가하려고 하는 경우다.

  • 다음 처럼 정액 할인이 아는 정률 할인 정책을 추가하려 하는 시나리오다.

  • 따라서 다음과 같이 RateDiscountPolicy를 추가해 할인 구현체를 갈아끼울 것이다.

  • RateDiscountPolicy를 생성한다.

  • Junit을 통해 실제로 vip할인이 이뤄지는지 테스트한다.
  • 실패 테스트도 만들어준다. basic이면 할인가격이 0이다.

만든 할인 정책을 서비스에 적용

  • 그런데 할인 정책을 서비스에 적용 하려면 구현체인 OrderServiceImpl에서 FixDiscountPolicy를 RateDiscountPolicy로 바꾸는 코드 수정을 해야 한다. 즉 FixDiscountPolicy라는 구체적인 구현체에 이미 의존하고 있으므로 OCP DIP원칙을 위반하는 것이다. 클라이언트 코드에 영향을 주기 때문이다.
  • 따라서 DIP를 위반하지 않도록 인터페이스에만 의존하도록 의존관계를 변경하자

  • 이런 식으로 인터페이스에만 의존하도록 설계를 한다.
  • 그런데 구현체가 없는데 코드를 어떻게 실행하나?
  • 이를 실행하면 당연히 NPE가 날 수 밖에 없다. createOrder를 호출할 때 discountPolicy에 아무 값도 할당이 되지 않았기 때문이다.
  • 이를 해결하기 위해서는 누군가가 클라이언트인 OrderServiceImpl에 DiscountPolicy의 구현 객체를 대신 생성하고 주입해야 한다.

관심사의 분리

  • 위의 코드는 마치 배우에게 직접 상대 여자 주인공을 선택해야 하는 역할을 부여하는 것과 같다. 명확히 관심사를 분리해야 한다. 배우는 배역을 수행하는 것에만 신경쓰고, 배우를 선택하는 공연 기획자가 필요하다.

APPCONFIG의 등장

  • 따라서 애플리케이션의 전체 동작 방식을 구성(config)하기 위해 구현 객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스를 만들어야 한다.

  • 다음과 같이 MemberServiceImpl의 생성자를 만든다. final로 선언된 상태에서 생성자를 만들면 무조건 파라미터로 할당되도록 생성자가 만들어진다.

  • AppConfig 클래스를 생성하여 AppConfig가 MemoryMemberRepository() 구현 객체를 생성하고 이를 연결하도록 한다.
  • 이제 MemberServiceImpl에는 MemoryMemberRepository() 관련 코드가 없다.
  • 이를 생성자를 통해 객체가 들어온다고 하여 생성자 주입 이라 한다.


  • 이런 식으로 OrderServiceImpl 역시 생성자 주입으로 저장소와 할인정책 구현 객체를 넘길 수 있다.

  • 즉 AppConfig는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성하고, 생성한 객체 인스턴스의 참조(레퍼런스)를 생성자를 통해서 주입한다.

  • 이제 객체를 생성하고 연결하는 역할(AppConfig)과 실행(OrderserviceImpl)하는 역할, 즉 관심사가 명확히 분리되었다.

  • appConfig 객체는 memoryMemberRepository 객체를 생성하고 그 참조값을 memberServiceImpl을 생성하면서 생성자로 전달한다.

  • 클라이언트인 memberServiceImpl 입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 "DI(Dependency Injection)" 우리말로 의존관계 주입 또는 의존성 주입이라 한다.


  • 이제 메인 앱에서 appconfig에게 memberService 혹은 orderService를 달라고 요청하여 받아오면 된다.


  • 테스트코드 역시 Appconfig를 사용하는데, 이때 @BeforeEach를 사용하면 테스트를 실행하기 전에 이를 먼저 실행하여 위의 memberService, 혹은 orderService에 값을 할당해준다.
  • 이제 AppConfig를 조금 리팩토링 할 필요성이 있다.
profile
하마드

0개의 댓글