DIP, OCP 원칙
DIP(Dependency Injection) 과 OCP (Open Closed Principle)은 스프링 프로젝트에서 관심사 분리를
통해 보다 훌륭한 프로젝트를 만드는 것을 도와준다
코드를 통해 *DIP, *OCP를 알아보자
- 커피점에서 커피값을 할인할 때 할인정책을 정역할인해줄지, 퍼센테이지로 할인해줄지 아직
- 정해지지 않았다
- 이때, 다형성을 이용하여 기능 구현을 하면 두개의 기능을 만들어놓고 끼워 넣기만 하는 상황이된다
- 위에 같은 상황일때, 구현 객체 코드에서 변경이 생기면 OCP 정책에 위반하게 된다
- 이 상황을 해결하기 위해서 외부 의존관계 주입을 통해 해결한다.
*프로그래머는 “추상화에 집중해야지, 구현화에 집중해서는 안된다”
*소프트웨어 개체(클래스, 모듈 등) 은 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀야함
클라이언트 → 주문 생성 → 주문 서비스 수행 → 할인 정책 수행
위에 순서로 코드 진행이지만 이해를 위해 주문 서비스 수행과 할인 정책 수행 코드만 살펴보겠다
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository = new MemoryMemberRepository()
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
//다형성은 지켰지만 DI원칙을 지키지 못했고
//변경 시 OCR원칙을 지키지 못한다
@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);
}
}
위 코드에 경우 인터페이스가 객체를 직접 설정하는 일이 생기게되어 DI 원칙에 위배된다
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);
}
}
DIP 원칙을 지키기 위해서 생성자를 만들어 의존관계를 설정할 수 있다
이 경우 Config 파일을 만들어서 의존객체를 주입해주어야한다
이것을 DIP라고 하며 자연스럽게 OCP원칙이 지켜지게된다
public class AppConfig{
public MemberService memberService() {
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
}
}
위와 같이 의존객체를 주입해줄수있다
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(MemberRepository());
}
private MemoryMemberRepository MemberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService(){
return new OrderServiceImpl(MemberRepository(), discountPolicy());
}
private DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
리펙터링하여 보면 위와 같이 된다
만약 할인 정책을 변경 해야할 경우 주석처리 하여 사용할 수 있다
이때, 인터페이스인 OrderImpl에서 변경이 일어나지 않고 Config인 외부의 변경으로 의존객체가
변경이 되는것이 OCP정책을 지킨 개발이다
또한, Config 클래스를 IoC컨테이너, DIP컨테이너, 어셈블러, 오브젝트 팩토리 라고 부른다
'프로그래밍언어 > Java' 카테고리의 다른 글
[Java] 스프링과 싱글톤 패턴의 관계 (Configuration) (0) | 2022.01.19 |
---|---|
[Java]웹 어플리케이션과 싱글톤 (0) | 2022.01.18 |
스프링 자동 의존관계 , 수동 의존관계 (0) | 2022.01.13 |
스프링 회원 조회 기능 구현 (0) | 2022.01.12 |
스프링 웹 방식 (0) | 2022.01.11 |
댓글