SOLID (2)

Manx·2022년 4월 29일
0

spring

목록 보기
5/24

SOLID를 철저하게 지켰음에도 불구하고 OCP, DIP를 위반하는 일들이 종종 존재한다.
예를 들어

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

다음과 같이 역할과 구현을 구분했음에도 불구하고 기능을 확장, 수정하려면 다음과 같이 수행 코드를 변경해야 하는 일이 발생한다.
이 이유는 OrderServiceImpl가 discountPolicy 인터페이스를 의존하고 있지만, 동시에 RateDiscountPolicy, FixDiscountPolicy 즉 구현 클래스도 의존하고 있기 때문이다.
그렇다면 우리는 기능이 변경될 때마다 수많은 클래스를 변경해야 하는 문제를 만나게 될 수 있다.

해결책은 다른 무언가를 통해 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 MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    
    public DiscountPolicy discountPolicy() {
        // 사용영역의 코드 수정없이 기능을 확장, 변경할 수 있게 되었다.
        return new RateDiscountPolicy();
    }
    
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
}

다음과 같이 AppConfig를 통해 주입을 받게 하면 된다.
이렇게 하면, 기능을 변경할 때 마다 OrderServiceImpl클래스 변경 없이 AppConfig만 변경해주면 되므로 객체지향의 원칙이 잘 지켜지게 된다.
즉, 사용 영역의 코드가 아닌 구성영역의 코드만 변경해주면 된다.
이렇게 인젝션 해주는 AppConfig같은 부분을 IoC컨테이너 또는 D.I 컨테이너 라고 한다.


Reference

  • 스프링 핵심 원리 기본편 - 김영한 강사님
profile
백엔드 개발자

0개의 댓글