객체 지향 원리 적용 - 관심사의 분리

 

객체 지향 원리 적용 - 새로운 할인 정책 개발 및 적용 과 문제점

 

write-read.tistory.com

AppConfig 등장

애플리케이션의 전체 동작 방식을 구성(Config)하기 위해 , 구현객체를 생성하고 , 연결하는 책임을 가지는 별도의 설정 클래스를 만들자

package hello.core;

import hello.core.discount.FixDiscountPolicy;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import 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를 통해서 MemberSerivce 사용할 때 MemberService의 구현체(MemberServiceImpl)가 생성이 되는데 그 때 생성자 메소드 매개변수로 MemoryMemberRepository를 넣어준다. (생성자 주입)

 

MemberServiceImpl

package hello.core.member;

public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {	// 생성자 주입으로 변경
        this.memberRepository = memberRepository;
    }

    @Override
    public void join(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

OrderServiceImpl

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;

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;
    }

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member , itemPrice);

        return new Order(memberId , itemName , itemPrice , discountPrice);
    }
}
  • AppConfig는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성 한다.
    • MemberServiceImpl
    • MemoryMemberServiceImpl
    • OrderServiceImpl
    • FixDiscountImpl
  • AppConfig는 생성한 객체 인스턴스의 참조(레퍼러슨)를 생성자를 통해서 주입(연결) 해준다.
    • MemberServiceImpl -> MemoryMemberRepository
    • OrderServiceImpl -> MemoryMemberRepository , FixDiscountPolicy
  • 설계 변경으로 MemberServiceImpl은 MemoryMemberRepository를 의존하지 않는다.
  • 단지 MemberRepository인터페이스만 의존한다.
  • MemberServiceImpl입장에서 생성자를 통해 어떤 구현 객체가 들어올지(주입될지)는 알 수 없다.
  • MemberServiceImpl의 생성자를 통해서 어떤 구현 객체를 주입할지는 오직 외부 (AppConfig)에서 결정된다.
  • MemberServiceImpl은 이제부터 의존관계에 대한 고민은 외부에 맡기고 실행에만 집중하면 된다.

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

 

 

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

 

 

스프링 핵심 원리 - 기본편 - 인프런

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다. 초급 프레임워크 및 라이브러리 웹 개발 서버 개발 Back-End Spring 객체지향 온

www.inflearn.com