새로운 정책 개발
코드에서 다형성을 잘 사용하는 경우 새 정책을 추가하는 것은 문제가 되지 않습니다.
그러나 새로운 정책의 적용에 문제가 있다.
- 클라이언트 코드순차 서비스 구현도 변경해야 합니다.
- 클라이언트는 구현과 인터페이스 모두에 의존합니다 → DIP 위반
관심사의 분리
- AppConfig는 구현 개체를 만들고 연결하는 역할을 합니다.
- 앱 구성의 출현으로 더 이상 기존 클라이언트 코드에서 구현을 만들 필요가 없습니다.
- 결과적으로 클라이언트 개체는 자신의 역할 수행에만 집중하고 권한은 축소됩니다(책임이 명확해짐).
AppConfig 리팩토링
- 명확한 역할 분리 및 구성 정보 구현
- 역할이 잘 어울린다
- 중복 제거
이전 코드
public class OrderServiceImpl implements OrderService {
// OrderService는 생성(new), 연결, 실행 등 다양한 책임이 있음
// 인터페이스(DiscountPolicy)뿐만 아니라, 구현체(FixDiscountPolicy)에도 의존관계임
// 만약 FixDiscountPolicy -> newDiscountPolicy로 변경한다면 FixDiscountPolicy 구현체를 사용하는 모든 코드를 수정해야함
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
...
}
리팩토링 코드
public class OrderServiceImpl implements OrderService {
// 인터페이스에만 의존관계
private final DiscountPolicy discountPolicy;
//생성자 추가
public OrderServiceImpl(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
...
}
public class AppConfig {
// OrderService에 구현체(discountPolicy)를 주입하고 있음
public OrderService orderService() {
return new OrderServiceImpl(discountPolicy());
}
public DiscountPolicy discountPolicy() {
// 새로운 정책을 변경해야한다면, 이 부분만 수정하면 됌
// return new FixDiscountPolicy();
return new newDiscountPolicy();
}
}
졸업 증서
- 앱 구성의 출현으로 사용 영역과 객체 생성 및 구성 영역으로 구분
- 할인 정책이 변경되더라도 앱 구성. 적용 분야는 변경할 필요가 없습니다.
좋은 객체지향 설계의 5가지 원칙 적용
개인 책임의 SRP 원칙
클래스는 하나의 책임만 가져야 합니다.
- 기존 클라이언트 개체에는 다음과 같은 다양한 역할과 책임이 있었습니다. B. 구현 개체의 생성, 연결 및 실행.
- AppConfig를 통한 관심사 분리, 클라이언트 개체는 작업만 담당
DIP 종속성 역전의 원리
프로그래머는 “물화가 아니라 추상화에 의존”해야 합니다. 종속성 주입은 이 원칙을 따르는 한 가지 방법입니다.
- 새로운 정책을 개발하고 수정하면서 클라이언트 코드도 변경해야 했습니다. (기존 클라이언트 코드도 구체적인 구현 클래스에 의존함)
- AppConfig는 클라이언트 코드 대신 개체 인스턴스를 만들어 클라이언트 코드에 종속성을 주입하는 DIP 원칙을 따랐습니다.
OKP
소프트웨어 요소는 확장에는 열려 있어야 하지만 수정에는 닫혀 있어야 합니다.
- 다형성이 사용되고 클라이언트가 DIP를 고수한다면 무한히 확장 가능합니다.
- 응용 프로그램을 사용 도메인과 구성 도메인으로 나눕니다.
- 소프트웨어 요소가 새롭게 확장되더라도 사용 영역의 변경은 완료됩니다.
![[알고리즘] 정렬(Sort) 심화 [알고리즘] 정렬(Sort) 심화](https://file.foodle.kr/wp-content/plugins/contextual-related-posts/default.png)