요구사항에 따른 코드 구현 및 설계도는 생략하였다.
□ 문제점 코드
public class OrderServiceImpl implements OrderService {
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
}
이런 코드의 경우 OrderServiceImpl 는 Interface인 OrderService 에 의존하고 있다. (설계된 의도)
FixDiscountPolicy(), RateDiscountPolicy()를 직접적으로 객체를 생성하므로 두 클래스에도 의존을 하게된다. → DIP를 지키지 못했다.
□ 원래 목적
□ 잘못된 의도
□ 요구사항이 변경된 경우 클라이언트 코드를 직접 수정해야함
클라이언트 코드를 수정하여 OCP를 위반한다.
해결방법
- Interface에 의존하게끔 변경한다.
public class OrderServiceImpl implements OrderService {
//private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
private DiscountPolicy discountPolicy;
}
- 외부 클래스를(AppConfig) 생성하여 객체를 주입시켜 준다.
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(
new MemoryMemberRepository(),
new FixDiscountPolicy());
}
}
- OrderServiceImpl에 생성자 생성
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;
}
}
위와 같은 방식으로 수정하면
□ 변경된 후 클래스 다이어그램
조금 더 코드를 깔끔하게 수정하면!!
□ 리팩토링한 AppConfig
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public DiscountPolicy discountPolicy() {
return new FixDiscountPolicy();
}
}
메소드를 각자의 역할에 맞게 분리하였다.
결론
이렇듯 interface로 역할을 나눈 뒤 class가 역할을 수행하도록만 구현하면 요구사항이 변해도 손쉽게 갈아끼울 수 있다.
요구사항이 변해도 사용 영역의 코드는 변하면 안된다!! (중요!)
→ 사용 영역 코드가 변한다면 잘못 설계한 것! 🫢
'Backend > Spring' 카테고리의 다른 글
Component Scan (0) | 2024.01.09 |
---|---|
Singleton Container (0) | 2024.01.09 |
Container와 Bean (0) | 2024.01.08 |
객체지향원칙 5가지 (0) | 2024.01.04 |