우아한테크코스 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