02. Spring Basic - AppConfig

MoonJaeGyeong·2023년 8월 17일

Spring

목록 보기
2/10

1. 주문과 할인 예시


간단하게 주문과 할인이 가능한 주문 도메인을 아래와 같이 짠다면.

주문 도메인

역할과 구현을 분리하여 OOP 즉 객체 지향을 지키면서 SRP, OCP, DIP 등을 따르면서 구현을 한다면 아래와 같은 형태일 것 이다.

주문 도메인 클래스 다이어그램

하지만 순수 Java 코드로 구현을 하다보니

public class OrderServiceImpl implements OrderService {
	private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
    // 고정 할인 정책
 }

위와 같이 구현이 되었다.

2. 문제점 발견


위와 같은 경우에서는 만약 고정 할인 정책을 다른 할인 정책으로 바꿔주게 된다면 구현쪽 클래스의 코드 또한 변경을 해줘야 하는 문제점이 생긴다.

왜 그럴까?

  • 역할과 구현을 충실히 분리했는가? -> YES
  • 다형성도 활용하고, 인터페이스와 구현 객체를 분리했는가? -> YES
  • OCP, DIP 같은 객체지향 설계 원칙을 충실히 준수했는가? -> NO

위의 의존 관계를 분석해보면 인터페이스만이 아닌 아래와 같이 구현 클래스에도 의존을 하고 있다.

실제 의존관계

  • 할인 정책을 바꿀 때 OderServiceImpl 의 소스를 변경해야 한다 : OCP 위반
  • 구현 클래스에도 의존을 하고 있다 : DIP 위반

3. 문제 해결


3.1 해결방안

이 문제를 해결하기 위해서는 OderServiceImpl 에 DiscountPolicy의 구현 객체를 대신 생성하고 주입 해주어야 한다.

3.2 AppConfig

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

public class AppConfig {
	public OrderService orderService() {
		 return new OrderServiceImpl(
		 memberRepository(),
 		 discountPolicy());
	 }
 	public MemberRepository memberRepository() {
 		return new MemoryMemberRepository();
 	}
 	public DiscountPolicy discountPolicy() {
 	return new RateDiscountPolicy();
  	}
}

그리고 OrderSerivceimpl 에는 생성자를 주입한다.

public class OrderServiceImpl implements OrderService {
 	private final MemberRepository memberRepository;
	private final DiscountPolicy discountPolicy;
    
 	public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicydiscountPolicy) {
 		this.memberRepository = memberRepository;
 		this.discountPolicy = discountPolicy;
 }

4. 결론


4.1 IoC (Inversion of Control)

  • 기존 프로그램은 클라이언트 구현 객체가 스스로 서버 구현 객체를 생성 ,연결 ,실행 했다.

  • 반면 AppConfig 의 등장 이후에 프로그램의 제어 흐름을 모두 AppConfig 가 가져간다.

  • OrderServiceImple 또한 AppConfig 가 생성하고 할당한다.

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

4.2 DI (Dependency Injection)

  • 클래스 다이어그램을 보면 OrderServiceImpl 은 DiscountPolicy ,MemberRepository 에 의존 한다는 것을 알 수 있다. 하지만 실제 어떤 객체가 OrderServiceImple 에 할당 될지 알 수 없다

클래스 다이어그램

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

<출처 : 스프링 핵심 원리 - 기본편 by 김영한>

profile
내 맘대로 끄적이는 개발 블로그

1개의 댓글

comment-user-thumbnail
2023년 8월 17일

좋은 글 감사합니다.

답글 달기