Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Chapter 11_03 합성 관계로 변경하기 #62

Closed
Tracked by #59
jongfeel opened this issue Jun 11, 2022 · 0 comments
Closed
Tracked by #59

Chapter 11_03 합성 관계로 변경하기 #62

jongfeel opened this issue Jun 11, 2022 · 0 comments
Assignees
Labels
2022 오브젝트 코드로 이해하는 객체지향 설계

Comments

@jongfeel
Copy link
Owner

jongfeel commented Jun 11, 2022

03 합성 관계로 변경하기

컴파일 의존성에 속박되지 않고 다양한 방식의 런타임 의존성을 구성할 수 있다는 것이 합성이 제공하는 가장 커다란 장점

기본 정책 합성하기

인터페이스 추가

public interface ReatePolicy {
    Money calculateFee(Phone phone);

기본 정책 구현, 일반 요금제와 심야 할인 요금제에서 개별 요금을 계산하는 방식을 제외하고 전체 처리 로직이 동일하므로 추상 클래스로 추가

public abstract class BasicRatePolicy implements RatePolicy {
    @Override
    public Money calculateFee(Phone phone) {
        ...
    }

    protected abstract Money calculateCallFee(Call call);
}

일반 요금제, calculateCallFee를 오버라이딩 해서 call의 요금을 계산하는 자신만의 방식을 구현

public class RegularPolicy extends BasicRatePolicy {
    @Override
    protected Money calcualteCallFee(Call call) {
    ...
    }
}

심야 할인 요금제도 유사한 방식으로 구현

public class NightlyDiscountPolicy extends BasicRatePolicy {
    @Override
    protected Money calcualteCallFee(Call call) {
    ...
    }
}

RatePolicy 참조를 통해 Phone 클래스 구현
다양한 요금 정책과 협력해야 하므로 RatePolicy interface로 정의
Phone class는 컴파일 타임 의존성을 구체적인 런타임 의존성을 대체하기 위해 생성자를 통해 RatePolicy 인스턴스에 대해 의존성을 주입받는다.

일반 요금제 통화 요금 계산

Phone phone = new Phone(new RegularPolicy(Money.wons(10), Duration.ofSeconds(10)));

심야 할인 요금제 계산

Phone phone = new Phone(new NightlyDiscountPolicy(Money.wons(5), Money.wons(10), Duration.ofSeconds(10)));

부가 정책 적용하기

다음 두 가지 제약에 따라 부가 정책을 구현

  • 부가 정책은 기본 정책이나 다른 부가 정책의 인스턴스를 참조할 수 있어야 한다. 다시 말해서 부가 정책의 인스턴스는 어떤 종류의 정책과도 함성될 수 있어야 한다.
  • Phone의 입장에서는 자신이 기본 정책의 인스턴스에게 메시지를 전송하고 있는지, 부가 정책의 인스턴스에게 메시지를 전송하고 있는지를 몰라야 한다. 다시 말해서 기본 정책과 부가 정책은 협력 안에서 동일한 '역할'을 수행해야 한다. 이것은 부가 정책이 기본 정책과 동일한 RatePolicy 인터페이스를 구현해야 한다는 것을 의미한다.

부가 정책 AdditionalRatePolicy 추상 클래스 구현

public abstract class AdditionalRatePolicy implements RatePolicy {
    private RatePolicy next;

    public AdditionalRatePolicy(RatePolicy next) {
        this.next = next;
    }

    @Override
    public Money calculateFee(Phone phone) {
    }
    abstract protected Money afterCalculated(Money fee);
}

세금 정책

public class TaxablePolicy extends AdditionalRatePolicy {

   ...

    @Override protected Money afterCalculated(Money fee) {
        return fee.plus(fee.times(taxRatio));
    }
}

기본요금 할인 정책

public class RateDiscountablePolicy extends AdditionalRatePolicy {

   ...

    @Override protected Money afterCalculated(Money fee) {
        return fee.minus(discountAmount);
    }
}

기본 정책과 부가 정책 합성하기

일반 요금제에 세금 정책을 조합할 경우

Phone phone = new Phone(
                                    new TaxablePolicy(0.05,
                                            new RegularPolicy(...));

일반 요금제에 기본 요금 할인 정책을 조합한 후 세금 정책 조합

Phone phone = new Phone(
                                    new TaxablePolicy(0.05,
                                            new RateDiscountablePolicy(Money.wons(1000),
                                                    new RegularPolicy(...));

객체를 조합하고 사용하는 방식이 상속을 사용한 방식보다 더 예측 가능하고 일관성이 있다

새로운 정책 추가하기

고정 요금제(FixedRatePolicy) 혹은 약정 할인 정책(AgreementDiscountablePolicy) 이라는 새로운 부가 정책이 필요하면 클래스를 추가만 하고 조합하면 된다.

많은 사람들이 코드 재사용을 위해 상속 보다는 합성을 사용하라고 하는지 이유를 이해할 수 있다.

객체 합성이 클래스 상속보다 더 좋은 방법이다.

코드를 재사용하면서도 건전한 결합도를 유지할 수 있는 더 좋은 방법은 합성을 이용하는 것이다. 합성은 객체의 인터페이스를 사용한다.

상속을 사용해서는 안되는 것인지에 대한 의문은 구현 상속과 인터페이스 상속의 두 가지로 나눠야 한다는 사실을 이해해야 한다.
현재까지 언급한 상속의 단점은 구현 상속에 속한다.

@jongfeel jongfeel self-assigned this Jun 11, 2022
@jongfeel jongfeel added 2022 오브젝트 코드로 이해하는 객체지향 설계 labels Jun 11, 2022
@jongfeel jongfeel moved this from Todo to In Progress in 2022 jongfeel's study tasks Jun 18, 2022
Repository owner moved this from In Progress to Done in 2022 jongfeel's study tasks Jun 25, 2022
@jongfeel jongfeel moved this to Done in Object Sep 20, 2022
@jongfeel jongfeel added this to Object Sep 20, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
2022 오브젝트 코드로 이해하는 객체지향 설계
Projects
No open projects
Status: Done
Development

No branches or pull requests

1 participant