Skip to content

Commit

Permalink
Chapter 11 을 공부하라 #8
Browse files Browse the repository at this point in the history
Chapter 11 을 공부하라
  • Loading branch information
johngrib authored Apr 12, 2020
2 parents c2f5dd0 + 42f7db2 commit caf4830
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 0 deletions.
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)))));
}
}

0 comments on commit caf4830

Please sign in to comment.