Skip to content

Commit c05c319

Browse files
authored
Chapter 04 를 공부하고 테스트 코드를 추가하라 #3
Chapter 04 를 공부하고 테스트 코드를 추가하라
2 parents 4df4176 + 721db76 commit c05c319

11 files changed

Lines changed: 660 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
public class Customer {
4+
private String name;
5+
private String id;
6+
7+
public Customer(String name, String id) {
8+
this.name = name;
9+
this.id = id;
10+
}
11+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
import lombok.Builder;
4+
import lombok.Getter;
5+
6+
import java.time.DayOfWeek;
7+
import java.time.LocalTime;
8+
9+
public class DiscountCondition {
10+
@Getter
11+
private DiscountConditionType type;
12+
private int sequence;
13+
private DayOfWeek dayOfWeek;
14+
private LocalTime startTime;
15+
private LocalTime endTime;
16+
17+
public DiscountCondition(DiscountConditionType type, int sequence) {
18+
this.type = type;
19+
this.sequence = sequence;
20+
}
21+
22+
public DiscountCondition(DiscountConditionType type, DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) {
23+
this.type = type;
24+
this.dayOfWeek = dayOfWeek;
25+
this.startTime = startTime;
26+
this.endTime = endTime;
27+
}
28+
29+
public DiscountCondition(DiscountConditionType type, int sequence, DayOfWeek dayOfWeek, LocalTime startTime, LocalTime endTime) {
30+
this.type = type;
31+
this.sequence = sequence;
32+
this.dayOfWeek = dayOfWeek;
33+
this.startTime = startTime;
34+
this.endTime = endTime;
35+
}
36+
37+
public boolean isDiscountable(DayOfWeek dayOfWeek, LocalTime time) {
38+
if (type != DiscountConditionType.PERIOD) {
39+
throw new IllegalArgumentException();
40+
}
41+
return this.dayOfWeek.equals(dayOfWeek)
42+
&& this.startTime.compareTo(time) <= 0
43+
&& this.endTime.compareTo(time) >= 0;
44+
}
45+
46+
public boolean isDiscountable(int sequence) {
47+
if (type != DiscountConditionType.SEQUENCE) {
48+
throw new IllegalArgumentException();
49+
}
50+
return this.sequence == sequence;
51+
}
52+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
public enum DiscountConditionType {
4+
SEQUENCE, // 순번 조건
5+
PERIOD // 기간 조건
6+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
import com.johngrib.objects._02_movie.Money;
4+
import lombok.Builder;
5+
import lombok.Getter;
6+
7+
import java.time.Duration;
8+
import java.time.LocalDateTime;
9+
import java.util.List;
10+
11+
@Getter
12+
public class Movie {
13+
private String title;
14+
private Duration runningTime;
15+
private Money fee;
16+
private List<DiscountCondition> discountConditions;
17+
18+
private MovieType movieType;
19+
private Money discountAmount;
20+
private double discountPercent;
21+
22+
@Builder
23+
public Movie(String title, Duration runningTime, Money fee, List<DiscountCondition> discountConditions,
24+
MovieType movieType, Money discountAmount, double discountPercent) {
25+
this.title = title;
26+
this.runningTime = runningTime;
27+
this.fee = fee;
28+
this.discountConditions = discountConditions;
29+
this.movieType = movieType;
30+
this.discountAmount = discountAmount;
31+
this.discountPercent = discountPercent;
32+
}
33+
34+
public Money calculateAmountDiscountedFee() {
35+
if (movieType != MovieType.AMOUNT_DISCOUNT) {
36+
throw new IllegalArgumentException();
37+
}
38+
return fee.minus(discountAmount);
39+
}
40+
41+
public Money calculatePercentDiscountedFee() {
42+
if (movieType != MovieType.PERCENT_DISCOUNT) {
43+
throw new IllegalArgumentException();
44+
}
45+
return fee.minus(fee.times(discountPercent));
46+
}
47+
48+
public Money calculateNoneDiscountedFee() {
49+
if (movieType != MovieType.NONE_DISCOUNT) {
50+
throw new IllegalArgumentException();
51+
}
52+
return fee;
53+
}
54+
55+
/**
56+
* 할인 조건을 하나씩 훑어 가면서 할인 조건의 타입을 체크한 다음, 할인 가능 여부를 리턴한다.
57+
*
58+
* @param whenScreened 상영일시
59+
* @param sequence 상영순번
60+
* @return 할인 가능하다면 true
61+
*/
62+
public boolean isDiscountable(LocalDateTime whenScreened, int sequence) {
63+
for (DiscountCondition condition : discountConditions) {
64+
if (condition.getType() == DiscountConditionType.PERIOD) {
65+
if (condition.isDiscountable(whenScreened.getDayOfWeek(), whenScreened.toLocalTime())) {
66+
return true;
67+
}
68+
} else {
69+
if (condition.isDiscountable(sequence)) {
70+
return true;
71+
}
72+
}
73+
}
74+
return false;
75+
}
76+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
public enum MovieType {
4+
AMOUNT_DISCOUNT, // 금액 할인 정책
5+
PERCENT_DISCOUNT, // 비율 할인 정책
6+
NONE_DISCOUNT // 미적용
7+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
import com.johngrib.objects._02_movie.Money;
4+
import lombok.Getter;
5+
import lombok.Setter;
6+
7+
public class Reservation {
8+
@Getter
9+
@Setter
10+
private Customer customer;
11+
@Getter
12+
@Setter
13+
private Screening screening;
14+
@Getter
15+
@Setter
16+
private Money fee;
17+
@Getter
18+
@Setter
19+
private int audienceCount;
20+
21+
public Reservation(Customer customer, Screening screening, Money fee, int audienceCount) {
22+
this.customer = customer;
23+
this.screening = screening;
24+
this.fee = fee;
25+
this.audienceCount = audienceCount;
26+
}
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
import com.johngrib.objects._02_movie.Money;
4+
5+
public class ReservationAgency {
6+
public Reservation reserve(Screening screening, Customer customer, int audienceCount) {
7+
Money fee = screening.calculateFee(audienceCount);
8+
return new Reservation(customer, screening, fee, audienceCount);
9+
}
10+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.johngrib.objects._04_movie_data_system;
2+
3+
import com.johngrib.objects._02_movie.Money;
4+
5+
import java.time.LocalDateTime;
6+
7+
public class Screening {
8+
private Movie movie;
9+
private int sequence;
10+
private LocalDateTime whenScreened;
11+
12+
public Screening(Movie movie, int sequence, LocalDateTime whenScreened) {
13+
this.movie = movie;
14+
this.sequence = sequence;
15+
this.whenScreened = whenScreened;
16+
}
17+
18+
public Money calculateFee(int audienceCount) {
19+
switch (movie.getMovieType()) {
20+
case AMOUNT_DISCOUNT:
21+
if (movie.isDiscountable(whenScreened, sequence)) {
22+
return movie.calculateAmountDiscountedFee().times(audienceCount);
23+
}
24+
break;
25+
case PERCENT_DISCOUNT:
26+
if (movie.isDiscountable(whenScreened, sequence)) {
27+
return movie.calculatePercentDiscountedFee().times(audienceCount);
28+
}
29+
case NONE_DISCOUNT:
30+
return movie.calculateNoneDiscountedFee().times(audienceCount);
31+
}
32+
return movie.calculateNoneDiscountedFee().times(audienceCount);
33+
}
34+
}

0 commit comments

Comments
 (0)