OCP, DIP 같은 객체 지향 설계 원칙을 준수하지 못한 경우

도도·2023년 3월 22일
0

SPRING

목록 보기
2/14
public class OrderServiceImpl implements OrderService {
  //    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
      private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
  }

🤔문제점

DIP

  • 주문 서비스 클라이언트 (OrderServiceImpl) 는 DiscountPolicy 인터페이스에 의존하면서 DIP 를 지켰는데
    - 클래스 의존관계를 분석 -> 추상(인터페이스) 뿐 아니라 구체(구현) 클래스에도 의존
    • 추상(Interface)
      : DiscountPolicy
    • 구체(구현)
      :FixDiscountPolicy,RateDiscountPolicy

OCP

  • 위의 코드는 기능을 확장해서 변경하면, 클라이언트 코드에 영향을 줌 따라서 OCP를 위반

인터페이스에만 의존하도록 코드를 변경

public class OrderServiceImpl implements OrderService {
      //private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
      private DiscountPolicy discountPolicy;
}
  • 코드를 실행하면 Null Pointer Exception가 발생

    해결 방안
    누군가가 클라이언트인 OrderServiceImplDiscountPolicy의 구현객체를 대신 생성하고 주입해야한다


AppConfig 등장

  • 애플리케이션의 전체 동작 방식을 구성(config) 위해 , 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스 만들기
public class AppConfig {
      public MemberService memberService() {
          return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService() {
          return new OrderServiceImpl(
                  new MemoryMemberRepository(),
                  new FixDiscountPolicy());
}
 public DiscountPolicy discountPolicy() {
          return new FixDiscountPolicy();
    }
}
  • AppConfig에서 할인 정책 역할(DiscountPolicy)을 담당하는 구현을 FixDiscountPolicy객체로 변경하면
public DiscountPolicy discountPolicy() {
      // return new FixDiscountPolicy();
       return new RateDiscountPolicy();
    }

여기까지 순수한 자바 코드만으로 DI를 적용
스프링을 적용해보자

@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();
      }
}
  • AppConfi에 설정을 구성한다는 @Configuration 을 붙여준다
  • 각 메서드에 @Bean을 붙여준다
ApplicationContext applicationContext = new
  AnnotationConfigApplicationContext(AppConfig.class);
          MemberService memberService =
  applicationContext.getBean("memberService", MemberService.class);
          OrderService orderService = applicationContext.getBean("orderService",
  OrderService.class);
  • ApplicationContext스프링 컨테이너 라 함

  • 기존에는 개발자가 직접 자바코드로 모든 것을 했다면

  • 스프링 컨테이너로 부터 객체를 스프링 빈으로 등록하고

  • 스프링 컨테이너에서 스프링 빈을 찾아서 사용하도록 변경

    이 게시글은 인프런 김영한님의 스프링 강의을 통해 정리한 글입니다.

profile
공부한것 정리하는 중입니다~

0개의 댓글