Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/step4' into step5
Browse files Browse the repository at this point in the history
  • Loading branch information
is2js committed Jun 26, 2022
2 parents d1d7807 + 7fd9c2d commit 4b45709
Show file tree
Hide file tree
Showing 21 changed files with 602 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 62 additions & 0 deletions src/main/java/theater/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package theater;

import java.time.Duration;
import java.time.LocalDateTime;
import theater.discount.condition.PeriodCondition;
import theater.discount.condition.SequenceCondition;
import theater.discount.policy.DiscountPolicy;
import theater.discount.policy.factory.AmountCalculatorFactory;
import theater.domain.Customer;
import theater.domain.Money;
import theater.domain.Movie;
import theater.domain.Screening;
import theater.domain.theater.Theater;
import theater.domain.theater.TicketOffice;
import theater.domain.theater.TicketSeller;

public class Main {
public static void main(final String[] args) {
final Theater theater = new Theater(Money.of(100.0));

final DiscountPolicy discountPolicy = new DiscountPolicy(new AmountCalculatorFactory((Money.of(1000.0))));
discountPolicy.addCondition(new SequenceCondition(1));
discountPolicy.addCondition(new PeriodCondition(LocalDateTime.of(2019, 7, 7, 1, 00, 00)));

Movie movie = new Movie(
"spiderman",
Duration.ofMinutes(120L),
Money.of(5000.0),
discountPolicy
);

theater.addMovie(movie);

for (int day = 7; day < 32; day++) {
for (int hour = 10, seq = 1; hour < 24; hour +=3, seq++) {
theater.addScreening(
movie, //fk
new Screening(
seq,
LocalDateTime.of(2019, 7, day, hour, 00, 00),
100
)
);
}
}

final TicketOffice ticketOffice = new TicketOffice(Money.of(0.0));
theater.contractTicketOffice(ticketOffice, 10.0);

final TicketSeller ticketSeller = new TicketSeller();
ticketSeller.setTicketOffice(ticketOffice);

final Customer customer = new Customer(Money.of(20000.0));

for (Screening screening: theater.getScreening(movie)) {
customer.reserve(ticketSeller, theater, movie, screening, 2);
final boolean isOk = theater.enter(customer, 2);
System.out.println("isOk = " + isOk);
break;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package theater.discount.condition;

import theater.domain.Screening;

public interface DiscountCondition {
public boolean isSatisfiedBy(Screening screening, int audienceCount);
}
17 changes: 17 additions & 0 deletions src/main/java/theater/discount/condition/PeriodCondition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package theater.discount.condition;

import java.time.LocalDateTime;
import theater.domain.Screening;

public class PeriodCondition implements DiscountCondition {
private LocalDateTime whenScreened;

public PeriodCondition(final LocalDateTime whenScreened) {
this.whenScreened = whenScreened;
}

@Override
public boolean isSatisfiedBy(final Screening screening, final int audienceCount) {
return screening.whenScreened.equals(whenScreened);
}
}
16 changes: 16 additions & 0 deletions src/main/java/theater/discount/condition/SequenceCondition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package theater.discount.condition;

import theater.domain.Screening;

public class SequenceCondition implements DiscountCondition {
private int sequence;

public SequenceCondition(final int sequence) {
this.sequence = sequence;
}

@Override
public boolean isSatisfiedBy(final Screening screening, final int audienceCount) {
return screening.sequence == sequence;
}
}
35 changes: 35 additions & 0 deletions src/main/java/theater/discount/policy/DiscountPolicy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package theater.discount.policy;

import java.util.HashSet;
import java.util.Set;
import theater.discount.condition.DiscountCondition;
import theater.discount.policy.strategy.Calculator;
import theater.domain.Money;
import theater.domain.Screening;

public class DiscountPolicy {

private final Set<DiscountCondition> conditions = new HashSet<>();
private Calculator factory;

public DiscountPolicy(final Calculator factory) {
this.factory = factory;
}

public void addCondition(DiscountCondition discountCondition){
this.conditions.add(discountCondition);
}

public void copyCondition(DiscountPolicy discountPolicy){
discountPolicy.conditions.addAll(conditions);
}

public Money calculateFee(Screening screening, int count, Money fee){
for (final DiscountCondition condition : conditions) {
if (condition.isSatisfiedBy(screening, count)) {
return factory.calculateFee(fee);
}
}
return fee;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package theater.discount.policy.factory;

import theater.discount.policy.strategy.AmountCalculator;
import theater.discount.policy.strategy.Calculator;
import theater.domain.Money;

public class AmountCalculatorFactory implements Calculator {
private AmountCalculator cache;
private Money amount;

public AmountCalculatorFactory(final Money amount) {
this.amount = amount;
}

private synchronized Calculator getCalculator() {
if (cache == null) {
cache = new AmountCalculator(amount);
}

return cache;
}

@Override
public Money calculateFee(final Money fee) {
return getCalculator().calculateFee(fee);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package theater.discount.policy.factory;

import theater.discount.policy.strategy.Calculator;
import theater.discount.policy.strategy.NosaleCalculator;
import theater.domain.Money;

public class NosaleCalculatorFactory implements Calculator {
private NosaleCalculator cache;

private synchronized Calculator getCalculator() {
if (cache == null) {
cache = new NosaleCalculator();
}
return cache;
}

@Override
public Money calculateFee(final Money fee) {
return getCalculator().calculateFee(fee);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package theater.discount.policy.factory;

import theater.discount.policy.strategy.Calculator;
import theater.discount.policy.strategy.PercentCalculator;
import theater.domain.Money;

public class PercentCalculatorFactory implements Calculator {
private PercentCalculator cache;
private Double percent;

public PercentCalculatorFactory(final Double percent) {
this.percent = percent;
}

private synchronized Calculator getCalculator() {
if (cache == null) {
cache = new PercentCalculator(percent);
}
return cache;
}

@Override
public Money calculateFee(final Money fee) {
return getCalculator().calculateFee(fee);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package theater.discount.policy.strategy;

import theater.domain.Money;

public class AmountCalculator implements Calculator {
private Money amount;

public AmountCalculator(final Money amount) {
this.amount = amount;
}

@Override
public Money calculateFee(final Money fee) {
return fee.minus(amount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package theater.discount.policy.strategy;

import theater.domain.Money;

public interface Calculator {
Money calculateFee(Money fee);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package theater.discount.policy.strategy;

import theater.domain.Money;

public class NosaleCalculator implements Calculator {
public NosaleCalculator() {
}

@Override
public Money calculateFee(final Money fee) {
return fee;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package theater.discount.policy.strategy;

import theater.domain.Money;

public class PercentCalculator implements Calculator {
private Double percent;

public PercentCalculator(final Double percent) {
this.percent = percent;
}

@Override
public Money calculateFee(final Money fee) {
return fee.minus(fee.multi(percent));
}
}
28 changes: 28 additions & 0 deletions src/main/java/theater/domain/Customer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package theater.domain;

import theater.domain.theater.Theater;
import theater.domain.theater.TicketSeller;

public class Customer {

// 데이터 객체를, 태어난 이후 받는다면(구매), 미리 NULL객체로 초기화해서 상대방 확인시, NULL객체로 확인하게 한다.
public Reservation reservation = Reservation.NONE;
private Money amount; // VO필드는 재할당이 운명이라 not final이다.

public Customer(final Money amount) {
this.amount = amount;
}

// 거래(예매) 요청 -> 갑에 의해 물건을 받아와 자신이 가지니 setter역할로서 void로 정의한다
public void reserve(TicketSeller ticketSeller, Theater theater, Movie movie, Screening screening, int count){
reservation = ticketSeller.reserve(this, theater, movie, screening, count);
}

public boolean hasAmount(final Money amount) {
return this.amount.greaterThan(amount);
}

public void minusAmount(Money amount){
this.amount = this.amount.minus(amount);
}
}
33 changes: 33 additions & 0 deletions src/main/java/theater/domain/Money.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package theater.domain;

public class Money {

private final Double amount;

public Money(final Double amount) {
this.amount = amount;
}

public static Money of(final Double amount) {
return new Money(amount);
}

public Money minus(final Money amount) {
if (this.amount > amount.amount) {
return new Money( this.amount - amount.amount);
}
return new Money(0.0);
}

public Money plus(final Money amount){
return new Money(this.amount + amount.amount);
}

public Money multi(final double times) {
return new Money(this.amount * times);
}

public boolean greaterThan(final Money amount) {
return this.amount >= amount.amount;
}
}
26 changes: 26 additions & 0 deletions src/main/java/theater/domain/Movie.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package theater.domain;

import java.time.Duration;
import theater.discount.condition.DiscountCondition;
import theater.discount.policy.DiscountPolicy;

public class Movie<T extends DiscountPolicy & DiscountCondition> {
private final String title;
private final Duration duration;
private final Money fee;
private final DiscountPolicy policy;

public Movie(final String title,
final Duration duration,
final Money fee,
final DiscountPolicy policy) {
this.title = title;
this.duration = duration;
this.fee = fee;
this.policy = policy;
}

public Money calculateFee(Screening screening, int audienceCount){
return policy.calculateFee(screening, audienceCount, fee);
}
}

0 comments on commit 4b45709

Please sign in to comment.