애플리케이션을 하나의 공연이라 생각해보면 각각의 인터페이스를 배역(배우 역할)이라 생각해보자. 그런데 실제 배역에 맞는 배우를 선택하는 것은 누가 하는가?
로미오와 줄리엣 공연을 하면 로미오 역할은 누가 줄리엣 역할은 누가할지?
배우들이 정하는게 아니다.
이전 코드는 마치 로미오 역할(인터페이스)을 하는 레오나르도 디카프리오(구현체, 배우)가 줄리엣 역할(인터페이스)을 하는 여자 주인공(구현체,배우)을 직접 초빙하는 것과 같다.
디카프리오는 공연도 해야하고 동시에 여자 주인공도 공연에 직접 초빙해야하는 "다양한 책임"을 가지고 있다.
-스프링 핵심원리 /기본편 - 김영한강사님
스프링 프레임워크의 관심사 분리는 소프트웨어 개발에서의 각각의 관심사를 독립적으로 처리하고 분리하여 모듈화하는 개념이다.
이를 통해 코드의 가독성, 유지보수성, 재사용성이 향상되고 애플리케이션의 전체적인 구조가 명확해 진다. 스프링 프레임워크는 다양한 기능과 모듈을 제공하여 관심사 분리를 쉽게 구현할 수 있도록 해준다.
예를들어 하나의 인터페이스에 두개의 추상 메서드가 있는데 기능을 두개를 가지고 있다하면, 그 메서드를 사용하기 위해 사용자가 직접 코드를 바꿔주거나 지워주거나 해야한다. 이 부분에서 소스 코드를 변경해야하므로 OCP를 위반하고,
또 의존 관계를 맺을 때 추상화에 의존해야하는 DIP 즉 의존 역전원칙을 위반하게 되고 강제적으로 자신이 사용하지 않는 메서드에 의존 관계를 맺게 되므로 ISP 인터페이스 분리원칙도 위반하게 된다.
이를 해결하기 위해서는 DIP를 위반하지 않도록 오직 인터페이스에만 의존하도록 의존관계를 변경하면되는데.
인터페이스에만 의존하도록 코드를 변경하면된다.
하지만 인터페이스만 덩그러니 있게 된 상태에서 Test를 진행한다면 당연히 NullPointerException이 발생한다.
김영한 강사님의 말을 빌려쓰자면
"관심사를 분리하자"
공연을 구성하고, 담당 배우를 섭외하고, 역할에 맞는 배우를 지정하는 책임을 담당하는 별도의 "공연 기획자"가 나올 시점이다.
이를
AppConfig라고 한다.(꼭 정해져 있는 이름은 아니다..)
애플리케이션의 전체 동작 방식을 구성(config)하기 위해, "구현 객체를 생성" 하고 "연결"하는 책임을 가지는 별도의 설정 클래스를 만들어 준다.
Application의 전반적인 운영을 책임지는 중요한 부분이다.
각 Impl Class 에서는 Interface(추상메서드)에만 의존하고 구현부에는 의존하지 않게 끔 설계해준다.
AppConfig에서는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성한다.
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 에 등록된 구현 객체
- MemberServiceIpml
- MemoryMemberRepository
- OrderServceImpl
- FixDiscountPolicy
AppConfig는 생성한 객체 인스턴스의 참조(레퍼런스)를 생성자를 통해서 주입(연결)해준다.
- MemberServcieImpl 👉 MemoryMemberRepository
- OrderServiceImpl 👉 MemoryMemberRepository, FixDicountPolicy
이를 생성자 주입이라 한다.
의존관계에 대한 고민은 외부(AppConfig)에 맡기고 실행에만 집중한다.
'FrameWork > Spring' 카테고리의 다른 글
JPA (작성중) (0) | 2023.07.12 |
---|---|
Spring Framework에 대해 정리해보기 (1) | 2023.07.11 |
AOP란?🧑💻 (0) | 2023.07.01 |
Spring Interceptor (0) | 2023.06.23 |
Spring DI(Dependency Injection) (0) | 2023.06.19 |
댓글