[스프링 핵심 원리]-2

EarlyBird·2021년 10월 29일
0

스프링 핵심 원리

목록 보기
2/6
post-thumbnail

김영한님의 스프링 핵심 원리 강의 학습 내용입니다.

스프링 핵심 원리 이해

  • HashMap은 동시성 이슈 발생 가능성이 있다. 이 경우 ConcurrentHashMap을 사용해야 한다.

의존관계의 문제점

public class OrderServiceImpl implements OrderService{

//    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
    //...
    
 }
  • 인터페이스와 구현클래스 모두에 의존하고 있다. : DIP 위반
  • RateDiscountPolicy로 바꾸는 순간 OrderServiceImpl 소스 코드의 변경이 발생한다. : OCP 위반

해결방안

public class OrderServiceImpl implements OrderService{

//    private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
//    private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
    private DiscountPolicy discountPolicy;
}
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;
    }
    //...
}
public class AppConfig {
//기획자의 역할
//...

    public OrderService orderService(){
        return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy()); //생성자 주입
    }
}
  • 인터페이스에만 의존하고 있다.
  • OrderServiceImpl은 구체 클래스를 몰라도 된다.
  • AppConfig가 애플리케이션 실제 동작에 필요한 구현 객체를 생성한다.
  • AppConfig는 생성한 객체 인스턴스 참조를 생성자를 통해 주입해준다.
  • DI, 의존관계 주입

MemberApp, OrderApp

public class MemberApp {

    public static void main(String[] args) {
        MemberService memberService = new MemberServiceImpl();
        //...
}
public class MemberApp {

    public static void main(String[] args) {
        AppConfig appConfig = new AppConfig();
        MemberService memberService = appConfig.memberService();
        //...
}

Test

public class MemberServiceTest {

    MemberService memberService = new MemberServiceImpl();
    //...
}
public class MemberServiceTest {

    MemberService memberService;

    @BeforeEach
    public void beforeEach(){
        AppConfig appConfig = new AppConfig();
        memberService = appConfig.memberService();
    }
    //...
}

AppConfig 리팩터링

public class AppConfig {

    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository()); //생성자 주입
    }

    private MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy()); //생성자 주입
    }

    public DiscountPolicy discountPolicy(){
        return new FixDiscountPolicy();
    }
}
  • Extract Method : Ctrl + Alt +M
  • 역할과 구현을 분리 : SRP
  • 역할과 구현 클래스를 볼 수 있다.
    public DiscountPolicy discountPolicy(){
//        return new FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
  • FixDiscountPolicy에서 RateDiscountPolicy로 바꿀 때 AppConfig만 변경하면 된다.
  • 사용영역의 코드는 변경할 필요가 없다. : OCP

IoC - 제어의 역전

  • 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것

의존관계

정적인 클래스 의존관계

  • 클래스의 import 코드만 보고 의존관계를 쉽게 판단
  • 애플리케이션을 실행하지 않아도 분석가능
  • Diagrams - Show Diagram - Show Dependencies

동적인 객체 인스턴스 의존관계

  • 애플리케이션 런타임에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해 클라이언트와 서버의 실제 의존관계가 연결된다 - DI(의존관계 주입)

DI

  • 클라이언트 코드를 변경하지 않고 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있다.
  • 정적인 클래스 의존관계를 변경하지 않고 동적인 객체 인스턴스 의존관계를 변경할 수 있다.

IoC 컨테이너, DI 컨테이너

  • 객체를 생성하고 관리하며 의존관계를 연결해 주는 것(EX) AppConfig)
profile
안되면 되게 합시다

2개의 댓글

comment-user-thumbnail
2021년 10월 29일

깔끔한 정리 너무 좋군요 ^^

1개의 답글

관련 채용 정보