우아한테크코스 4기/코드리뷰
[레벨2] 지하철 경로
giron
2022. 5. 28. 17:41
728x90
데코레이터 패턴
위와 같이 요금을 측정하는데, 나이와 거리에 따라 요금을 측정한다고 하자. 이때 나이와 거리의 조합에 따라서 요금이 결정된다고 생각했고 데코레이터 패턴을 적용해봤다.
<<Fare>>
public interface Fare {
double calculateExtraFare();
}
요금이 계산되는 메서드를 추가해준다.
BaseFare
public class BaseFare implements Fare{
private final int extraFare;
public BaseFare(final int extraFare) {
this.extraFare = extraFare;
}
@Override
public double calculateExtraFare() {
return extraFare + 1250;
}
}
기존 1250원에 라인에 따른 추가 요금을 받아서 반환해준다. 모든 요금 정책에 기본적으로 들어가는 금액을 BaseFare로 지정해준다.
Decorator
public class Decorator implements Fare{
private final Fare fare;
public Decorator(final Fare fare) {
this.fare = fare;
}
@Override
public double calculateExtraFare() {
return fare.calculateExtraFare();
}
}
요금 정책들은 이 Decorator를 상속받아 요금을 추가해 나갑니다.
DistanceDecorator
public class DistanceDecorator extends Decorator{
private final int distance;
public DistanceDecorator(final Fare fare, final int distance) {
super(fare);
this.distance = distance;
}
@Override
public double calculateExtraFare() {
return super.calculateExtraFare() + DistanceExtraFare.valueOf(distance);
}
}
거리에 따른 요금을 더해줍니다. 거리를 받고 Enum에서 거리에 따라 알맞은 추가 요금을 더해줍니다.
AgeDecorator
public class AgeDecorator extends Decorator{
private final int age;
public AgeDecorator(final Fare fare, final int age) {
super(fare);
this.age = age;
}
@Override
public double calculateExtraFare() {
double price = super.calculateExtraFare();
return AgeFare.valueOf(age, price);
}
}
DistanceDecorator와 같습니다. 나이에 따른 값을 enum인 AgeFare에 넘겨줘서 알맞은 정책에 맞게 계산해주고 반환해줍니다.
클라이언트
위와 같이 기본 데코레이터를 조합해서 사용할 수 있습니다!
Service에서 Service참조 아니면 Repo참조
service 참조
- 순환 참조가 발생할 가능성이 있다.
- A라는 서비스에서 B라는 서비스를 불러올 때, B의 레포지토리에서 B의 서비스를 만들어줘야하는데 이 때, A서비스를 위한 B서비스가 만들어지는 게 아닌가 라는 생각을 해볼 수도 있다.
- 데이터가 분산되지 않고 관리하기 편할수있다.
Repository 참조
- service -> repo 라는 단방향 계층으로 순환 참조같은 상황을 걱정하지 않아도 된다.
- 여러 서비스에서 데이터를 쉽게 불러올수있어서 유연하다.
- 데이터를 가져오는 로직이 여러 서비스에 분산되어서 관리하기 어려울 수 있다.
저는 작은 프로젝트의 경우엔 service에서 repo를 가져오도록 할 것 같아요. 데이터가 분산되기 작은 경우고 유연하게 데이터를 가져올수 있기 때문입니다.
반면에 규모가 커지면 service에서 service도 참조해서 데이터가 분산되지 않도록 최대한 관리할 것 같습니다. 이때, B서비스에서 A라는 서비스를 위한 메서드를 여는 것인지를 고민하면서 사용할 것 같습니다.
728x90