오늘은 여러 ApprovalPolicy 구현체 중 실제로 어떤 정책을 사용할지 결정하는 ApprovalPolicyResolver를 분석했다.
프로젝트에는 다음과 같은 Policy 구현체가 존재한다.
NoApprovalPolicy
SingleApproverPolicy
DualApproverPolicy
이 객체들은 모두 Spring의 @Component로 등록되어 있다.
ApprovalPolicyResolver에서는 여러 Policy를 List<ApprovalPolicy>로 주입받는다.
public ApprovalPolicyResolver(List<ApprovalPolicy> policies) {
this.policiesByLevel = policies.stream()
.collect(Collectors.toMap(
ApprovalPolicy::getSupportedLevel,
Function.identity()
));
}
그리고 이를 Map으로 변환한다.
개념적으로 다음과 같은 구조가 된다.
NONE
→ NoApprovalPolicy
SINGLE_APPROVER
→ SingleApproverPolicy
DUAL_APPROVER
→ DualApproverPolicy
Service에서는 다음과 같이 필요한 정책을 찾는다.
approvalPolicyResolver.resolve(
stackPolicy.getApprovalLevel()
)
새로운 승인 정책이 추가된다고 생각해보았다.
예를 들어,
TRIPLE_APPROVER
정책이 추가된다면 기존 Service의 조건문을 수정하기보다 새로운 Policy 클래스를 추가할 수 있다.
TripleApproverPolicy
↓
ApprovalPolicy 상속
↓
@Component
↓
Resolver가 자동 주입
Spring의 DI는 단순히 객체를 생성하고 주입하는 기능만이 아니라 구현체를 유연하게 연결하고 확장 가능한 구조를 만드는 데 활용할 수 있다는 것을 실제 프로젝트를 통해 이해했다.