요구사항
지하철 미션에는 다음과 같은 요구사항이 있었다.
- 거리별 추가 요금 정책
- 노선별 추가 요금 정책
- 연령별 요금 할인 정책
인터페이스 사용
요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.
public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}
public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }
모든 요금 정책을 포함하는 새로운 요금 정 책 만들기
나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.
public class SubwayFarePolicy implements FarePolicy {
private final List<FarePolicy> farePolicies;
public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}
@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}
따라서 그림으로 본다면 다음과 같은 구조가 된다.
정책의 순서
지하철 요구사항은 순서가 중요했다.
금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.
@Configuration
public class FareConfiguration {
@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}