Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Chapter 11 을 공부하라 #8

Merged
merged 17 commits into from
Apr 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
61bd8d5
실습 대상인 10장 코드를 가져오라
johngrib Apr 8, 2020
6f8b9f6
일반 요금제에 세금 정책을 조합한 클래스를 추가하라
johngrib Apr 9, 2020
30271de
Phone에 afterCalculated 메소드를 추가하라
johngrib Apr 8, 2020
577b89b
afterCalculated 메소드의 기본 구현을 제공하라
johngrib Apr 8, 2020
bb652f5
TexableRegularPhone 의 계산 요금에 세금을 부과하라
johngrib Apr 9, 2020
babf23d
심야 할인 요금제에 세금을 부과하라
johngrib Apr 9, 2020
0fe3771
일반 요금제와 기본 요금 할인 정책을 조합한 RateDiscountableRegularPhone을 추가하라
johngrib Apr 9, 2020
f21cd26
심야 할인 요금제와 기본 요금 할인 정책을 조합한 RateDiscountableNightlyDiscountPhone 을 추가하라
johngrib Apr 9, 2020
0ceb4c4
합성 관계로 변경: RatePolicy 인터페이스를 추가하라
johngrib Apr 9, 2020
7d0a60d
합성 관계로 변경: 중복 코드를 담을 추상 클래스를 추가하라
johngrib Apr 9, 2020
59c5085
일반 요금제를 구현하라
johngrib Apr 9, 2020
c190959
심야할인 요금제를 구현하라
johngrib Apr 10, 2020
ece0d29
기본 정책으로 요금을 계산할 수 있도록 Phone을 수정하라
johngrib Apr 10, 2020
d398547
부가 정책을 AdditionalRatePolicy 추상 클래스로 표현하라
johngrib Apr 11, 2020
551341c
세금 정책을 추가하라
johngrib Apr 11, 2020
7451613
기본 요금 할인 정책을 추가하라
johngrib Apr 11, 2020
42f7db2
Phone 클래스의 사용 방법을 기록하라
johngrib Apr 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

public abstract class AdditionalRatePolicy implements RatePolicy {
private RatePolicy next;

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

@Override
public Money calculateFee(Phone phone) {
Money fee = next.calculateFee(phone);
return afterCalculated(fee);
}

protected abstract Money afterCalculated(Money fee);
}
17 changes: 17 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/BasicRatePolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

public abstract class BasicRatePolicy implements RatePolicy {
@Override
public Money calculateFee(Phone phone) {
Money result = Money.ZERO;

for (Call call : phone.getCalls()) {
result.plus(calculateCallFee(call));
}
return result;
}

protected abstract Money calculateCallFee(Call call);
}
24 changes: 24 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/Call.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.johngrib.objects._11_call;

import lombok.Getter;

import java.time.Duration;
import java.time.LocalDateTime;

/**
* 개별 통화 시간.
*/
public class Call {
@Getter
private LocalDateTime from;
private LocalDateTime to;

public Call(LocalDateTime from, LocalDateTime to) {
this.from = from;
this.to = to;
}

public Duration getDuration() {
return Duration.between(from, to);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

import java.time.Duration;

public class NightlyDiscountPolicy extends BasicRatePolicy {
private static final int LATE_NIGHT_HOUR = 22;

private Money nightlyAmount;
private Money regularAmount;
private Duration seconds;

public NightlyDiscountPolicy(Money nightlyAmount, Money regularAmount, Duration seconds) {
this.nightlyAmount = nightlyAmount;
this.regularAmount = regularAmount;
this.seconds = seconds;
}

@Override
protected Money calculateCallFee(Call call) {
if (call.getFrom().getHour() >= LATE_NIGHT_HOUR) {
return nightlyAmount.times(call.getDuration().getSeconds() / seconds.getSeconds());
}
return regularAmount.times(call.getDuration().getSeconds() / seconds.getSeconds());
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/Phone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Phone {
private RatePolicy ratePolicy;

/** 전체 통화 목록 */
private List<Call> calls = new ArrayList<>();

public Phone(RatePolicy ratePolicy) {
this.ratePolicy = ratePolicy;
}

public List<Call> getCalls() {
return Collections.unmodifiableList(calls);
}

public Money calculateFee() {
return ratePolicy.calculateFee(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

public class RateDiscountablePolicy extends AdditionalRatePolicy {
private Money discountAmount;

public RateDiscountablePolicy(Money discountAmount, RatePolicy next) {
super(next);
this.discountAmount = discountAmount;
}

@Override
protected Money afterCalculated(Money fee) {
return fee.minus(discountAmount);
}
}
7 changes: 7 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/RatePolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

public interface RatePolicy {
Money calculateFee(Phone phone);
}
20 changes: 20 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/RegularPolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

import java.time.Duration;

public class RegularPolicy extends BasicRatePolicy {
public Money amount;
private Duration seconds;

public RegularPolicy(Money amount, Duration seconds) {
this.amount = amount;
this.seconds = seconds;
}

@Override
protected Money calculateCallFee(Call call) {
return amount.times(call.getDuration().getSeconds() / seconds.getSeconds());
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/johngrib/objects/_11_call/TaxablePolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;

public class TaxablePolicy extends AdditionalRatePolicy {
private double taxRatio;

public TaxablePolicy(double taxRatio, RatePolicy next) {
super(next);
taxRatio = taxRatio;
}

@Override
protected Money afterCalculated(Money fee) {
return fee.plus(fee.times(taxRatio));
}
}
76 changes: 76 additions & 0 deletions src/test/java/com/johngrib/objects/_11_call/PhoneTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.johngrib.objects._11_call;

import com.johngrib.objects._02_movie.Money;
import org.junit.jupiter.api.DisplayName;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.*;

@DisplayName("Phone")
class PhoneTest {

// 일반 요금제의 규칙에 따라 통화 요금을 계산하는 전화
Phone regularPolicyPhone() {
return new Phone(
new RegularPolicy(
Money.wons(10),
Duration.ofSeconds(10)));
}

// 심야 할인 요금제의 규칙에 따라 통화 요금을 계산하는 전화
Phone nightlyDiscountPolicyPhone() {
return new Phone(
new NightlyDiscountPolicy(
Money.wons(5),
Money.wons(10),
Duration.ofSeconds(10)));
}

// 일반 요금제에 세금 정책을 조합할 경우의 Phone 인스턴스를 생성하는 방법
Phone taxableRegularPolicyPhone() {
return new Phone(
new TaxablePolicy( // 세금 정책
0.05,
new RegularPolicy( // 일반 요금제
Money.wons(10),
Duration.ofSeconds(10))));
}

// 일반 요금제에 기본 요금 할인 정책을 조합한 결과에 세금 정책을 조합하는 방법
Phone regularRateDiscountTaxablePhone() {
return new Phone(
new TaxablePolicy( // 세금 정책
0.05,
new RateDiscountablePolicy( // 기본 요금 할인 정책
Money.wons(1000),
new RegularPolicy( // 일반 요금제
Money.wons(10),
Duration.ofSeconds(10)))));
}

// 순서를 바꾸는 것도 가능하다
Phone regularRateDiscountTaxablePhone1() {
return new Phone(
new RateDiscountablePolicy( // 기본 요금 할인 정책
Money.wons(1000),
new TaxablePolicy( // 세금 정책
0.05,
new RegularPolicy( // 일반 요금제
Money.wons(10),
Duration.ofSeconds(10)))));
}

// 같은 정책을 심야 할인 요금제에도 적용
Phone rateDiscountNightlyPhone() {
return new Phone(
new RateDiscountablePolicy(
Money.wons(1000),
new TaxablePolicy(
0.05,
new NightlyDiscountPolicy(
Money.wons(5),
Money.wons(10),
Duration.ofSeconds(10)))));
}
}