행동하는 객체 지향 원칙(노트용)


public class OrderServiceImpl implements OrderService {
  //    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
      private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
  }

– 위 코드는 구현 및 인터페이스(DiscountPolicy) >> DIP Violation에 따라 다름

– 변경으로 인해 OCP도 위반됨

   public class OrderServiceImpl implements OrderService {
      //private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
      private DiscountPolicy discountPolicy;
}

– 인터페이스에만 의존하는 디자인 변경, 구현이 없기 때문에 실행 중 NPE(NullPointerException) 발생

– AppConfig 클래스를 솔루션으로 생성

(응용 프로그램의 전체 동작을 구성하기 위해 구현 개체를 만들고 연결하는 설정 클래스)

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

– AppConfig는 애플리케이션의 실제 작동에 필요한 구현 개체를 생성합니다.

(MemberServiceImpl, MemoryMemberRepository, OrderServiceImpl, FixDiscountPolicy)

– AppConfig는 생성자를 통해 생성된 개체 인스턴스의 참조를 삽입합니다.

public class MemberServiceImpl implements MemberService {
        private final MemberRepository memberRepository;
        public MemberServiceImpl(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
}
        public void join(Member member) {
            memberRepository.save(member);
}
        public Member findMember(Long memberId) {
            return memberRepository.findById(memberId);
} }

– 설계 변경으로 인해 MemberServiceImpl은 MemoryMemberRepository에 의존하지 않고 MemberRepository 인터페이스에만 의존합니다.

MemberServiceImpl 관점에서 생성자를 통해 들어오는 구현 개체는 무엇입니까?(주사 여부)알 수 없다.

MemberServiceImpl 구현 개체가 생성자에 의해 주입되는 것은 외부입니다.

( 앱 구성 )하나를 결정

MemberServiceImpl 지금부터이다 중독에 대한 우려는 외부적이다두고 실행에만 집중

>> 개체 생성 및 연결 앱 구성 책임이 있으며, 개체를 만들고 연결하는 역할과 개체를 실행하는 역할 사이에는 명확한 구분이 있습니다.



앱 구성 객체는 memoryMemberRepository 객체 생성 및 참조 값 설정 MemberServiceImpl 생성하는 동안 생성자에게 전달됨

고객 MemberServiceImpl 이런 관점에서 볼 때 종속 관계는 외부에서 밀입국한 것처럼 보인다.

DI(의존성 주입) 한국어로는 의존성 주입 또는 의존성 주입이라고 합니다.

< Verwendete Beispielklasse: MemberApp >

public class MemberApp {
      public static void main(String() args) {
          AppConfig appConfig = new AppConfig();
          MemberService memberService = appConfig.memberService();
          Member member = new Member(1L, "memberA", Grade.VIP);
          memberService.join(member);
          Member findMember = memberService.findMember(1L);
          System.out.println("new member = " + member.getName());
          System.out.println("find Member = " + findMember.getName());
} }

– 위의 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();
	  }
}

새로운 MemoryMemberRepository() 이 중복 제거

>> 지금 MemoryMemberRepository 다른 구현으로 변경할 때 한 부분만 변경하면 됩니다.

앱 구성 역할과 구현 클래스를 한눈에 볼 수 있습니다.

. 전체 애플리케이션이 어떻게 구성되어 있는지 빠르게 이해

< 좋은 객체지향 설계의 5가지 원칙 >

– MSRP >> 구현 개체 생성 및 연결 담당 앱 구성책임이 있으며, 클라이언트 개체는 실행만 담당합니다.

– 딥 >> 고객 코드입니다 할인 정책 추상화 인터페이스에만 의존하도록 코드를 수정하십시오. 앱 구성가다 FixDiscountPolicy 클라이언트 코드 대신 개체 인스턴스를 생성하여 클라이언트 코드에 종속성 주입. 이런 식으로 잠수 원칙에 따라 문제를 해결

-OCP >> 앱 구성중독이있다 FixDiscountPolicy 비율할인정책 클라이언트 코드에 주입하므로 클라이언트 코드를 변경할 필요가 없습니다.

< 통제의 역전 (IOC: Inversion of Control) >

기존 프로그램에서 클라이언트 구현 개체 자체는 필요한 서버 구현 개체를 생성합니다.

, 연결하다, 실행

( 구현 개체는 프로그램 자체의 제어 흐름을 제어합니다.

개발자를 위한 자연스러운 흐름 )

앱 구성등장 후 구현 객체는 자신의 로직을 실행하는 역할만 하고, 프로그램의 제어 흐름은 이제 앱 구성가져

통제의 역전(IOC)라고.

< Framework / Bibliothek >

프레임워크는 내가 작성하는 코드를 구동합니다.

, 대신 실행하면 프레임워크가 올바른 것입니다.

. ( JUnit 예: 테스트 코드 )

반면에 내가 작성한 코드가 제어 흐름을 직접 담당하는 경우에는 프레임워크가 아니라 라이브러리입니다.

< IoC 컨테이너 / DI 탱크 >

앱 구성 개체 및 링크 종속성 만들기 및 관리 I.O.C 용기 또는 컨테이너말하다

최근에는 종속성 주입에 중점을 두었습니다.

컨테이너라고 함.

< AppConfig Spring으로 이동 >

@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();
      }
}

앱 구성에서 설정을 구성하는 것을 의미합니다.

@건설 추가

모든 방법에서 @콩 추가. 이렇게 하면 스프링 저장소에 스프링 빈으로 등록됩니다.

< Nutzung im Zusammenhang mit MemberApp >

public class MemberApp {
    public static void main(String() args) {
//        AppConfig appConfig = new AppConfig();
//        MemberService memberService = appConfig.memberService();
        ApplicationContext ac = new
AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService =
		ac.getBean("memberService", MemberService.class);
        Member member = new Member(1L, "memberA", Grade.VIP);
        memberService.join(member);
        Member findMember = memberService.findMember(1L);
        System.out.println("new member = " + member.getName());
        System.out.println("find Member = " + findMember.getName());
} }

애플리케이션 컨텍스트 펜홀더라고 합니다.

펜 용기 @건설 첨부된 앱 구성 문장(구성) 정보로 사용

@콩 반환된 객체를 Spring 컨테이너에 등록하려면 ( Spring 컨테이너에 등록된 객체를 Spring Bean이라고 합니다.

)

봄 콩 @콩 스프링 빈의 이름으로 추가된 메서드 이름을 사용합니다.

. ( 회원 서비스 , 주문 서비스 )

Spring Container를 통해 필요한 Spring Beans(물체)내가 찾아야 해 봄 콩 getBean() 이후 방법을 사용하여 찾을 수 있습니다.