๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŒˆ Chapter 4: ์„ค๊ณ„ ํ’ˆ์งˆ๊ณผ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„

  • ํ˜‘๋ ฅ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์‹œ์ง€๋ฅผ ์ฃผ๊ณ ๋ฐ›์€ ๊ฐ์ฒด๋“ค ์‚ฌ์ด์˜ ์ƒํ˜ธ์ž‘์šฉ์ด๋‹ค.
  • ์ฑ…์ž„์€ ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์™€ ํ˜‘๋ ฅํ•˜๊ธฐ ์œ„ํ•ด ์ˆ˜ํ–‰ํ•˜๋Š” ํ–‰๋™์ด๋‹ค.
  • ์—ญํ• ์€ ๋Œ€์ฒด ๊ฐ€๋Šฅํ•œ ์ฑ…์ž„์˜ ์ง‘ํ•ฉ์ด๋‹ค.
  • ๊ฐ์ฒด์ง€ํ–ฅ ์„ค๊ณ„๋ž€ ์˜ฌ๋ฐ”๋ฅธ ๊ฐ์ฒด์—๊ฒŒ ์˜ฌ๋ฐ”๋ฅธ ์ฑ…์ž„์„ ํ• ๋‹นํ•˜๋ฉด์„œ ๋‚ฎ์€ ๊ฒฐํ•ฉ๋„์™€ ๋†’์€ ์‘์ง‘๋„๋ฅผ ๊ฐ€์ง„ ๊ตฌ์กฐ๋ฅผ ์ฐฝ์กฐํ•˜๋Š” ํ™œ๋™์ด๋‹ค.
  • ์ฑ…์ž„์€ ๊ฐ์ฒด์˜ ์ƒํƒœ์—์„œ ํ–‰๋™์œผ๋กœ, ๋‚˜์•„๊ฐ€ ๊ฐ์ฒด์™€ ๊ฐ์ฒด ์‚ฌ์ด์˜ ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ์„ค๊ณ„ ์ค‘์‹ฌ์„ ์ด๋™์‹œํ‚ค๊ณ , ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ๊ณ  ์‘์ง‘๋„๊ฐ€ ๋†’์œผ๋ฉฐ ๊ตฌํ˜„์„ ํšจ๊ณผ์ ์œผ๋กœ ์บก์Šํ™”ํ•˜๋Š” ๊ฐ์ฒด๋“ค์„ ์ฐฝ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์„ ์ œ๊ณตํ•œ๋‹ค.

๐Ÿ“š ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์˜ํ™” ์˜ˆ๋งค ์‹œ์Šคํ…œโ€‹

  • ๊ฐ์ฒด์˜ ์ƒํƒœ๋Š” ๊ตฌํ˜„์— ์†ํ•œ๋‹ค. ๊ตฌํ˜„์€ ๋ถˆ์•ˆ์ •ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€ํ•˜๊ธฐ ์‰ฝ๋‹ค. ์ƒํƒœ๋ฅผ ๊ฐ์ฒด ๋ถ„ํ•  ์ค‘์‹ฌ์ถ•์œผ๋กœ ์‚ผ์œผ๋ฉด ๊ตฌํ˜„์— ๊ด€ํ•œ ์„ธ๋ถ€์‚ฌํ•ญ์ด ๊ฐ์ฒด์˜ ์ธํ„ฐํŽ˜์ด์Šค์— ์Šค๋ฉฐ๋“ค๊ฒŒ ๋˜์–ด ์บก์Šํ™”์˜ ์›์น™์ด ๋ฌด๋„ˆ์ง„๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ƒํƒœ์˜ ๋ณ€๊ฒฝ์€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ณ€๊ฒฝ์„ ์ดˆ๋ž˜ํ•˜๋ฉฐ ์ด ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด์—๊ฒŒ ๋ณ€๊ฒฝ์˜ ์˜ํ–ฅ์ด ํผ์ง„๋‹ค. ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์— ์ดˆ์ ์„ ๋งž์ถ”๋Š” ์„ค๊ณ„๋Š” ๋ณ€๊ฒฝ์— ์ทจ์•ฝํ•  ์ˆ˜ ๋ฐ–์— ์—†๋‹ค.
  • ๊ทธ์— ๋น„ํ•ด ๊ฐ์ฒด์˜ ์ฑ…์ž„์€ ์ธํ„ฐํŽ˜์ด์Šค์— ์†ํ•œ๋‹ค. ๊ฐ์ฒด์˜ ์ฑ…์ž„์„ ๋“œ๋Ÿฌ๋‚ด๋Š” ์•ˆ์ •์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค ๋’ค๋กœ ์ฑ…์ž„์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ƒํƒœ๋ฅผ ์บก์Šํ™”ํ•จ์œผ๋กœ์จ ๊ตฌํ˜„ ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ํŒŒ์žฅ์ด ์™ธ๋ถ€๋กœ ํผ์ ธ๋‚˜๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.

๐ŸŽˆ ๋ฐ์ดํ„ฐ๋ฅผ ์ค€๋น„ํ•˜์ž.โ€‹

  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„๋Š” ๊ฐ์ฒด๊ฐ€ ๋‚ด๋ถ€์— ์ €์žฅํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌด์—‡์ธ๊ฐ€๋ฅผ ๋ฌป๋Š” ๊ฒƒ์œผ๋กœ ์‹œ์ž‘ํ•œ๋‹ค.
  • Movie์— ์ €์žฅ๋  ๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์„ค๊ณ„๋ฅผ ์‹œ์ž‘ํ•œ๋‹ค.
public class Movie {
private String title; // ์ œ๋ชฉ
private Duration runningTime; // ์ƒ์˜์‹œ๊ฐ„
private Money fee; // ๊ธฐ๋ณธ ์š”๊ธˆ
private List<DiscountCondition> discountConditions;

private MovieType movieType;
private Money discountAmount;
private double discountPercent;
}
  • ์—ฌ๊ธฐ์„œ ์ฑ…์ž„ ์ค‘์‹ฌ์˜ Movie ํด๋ž˜์Šค์™€์˜ ์ฐจ์ด์ ์€ discountConditions, discountAmount, discountPercent ์ด Movie์•ˆ์— ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.
  • ํ• ์ธ ์ •์ฑ…์€ ์˜ํ™”๋ณ„๋กœ ์˜ค์ง ํ•˜๋‚˜๋งŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— MovieType์œผ๋กœ ์ƒํƒœ๋ฅผ ํ™•์ธํ•œ๋‹ค.
public enum MovieType {
AMOUNT_DISCOUNT, // ๊ธˆ์•ก ํ• ์ธ ์ •์ฑ…
PERCENT_DISCOUNT, // ๋น„์œจ ํ• ์ธ ์ •์ฑ…
NONE_DISCOUNT, // ๋ฏธ์ ์šฉ
}
  • ์ด์ฒ˜๋Ÿผ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„์—์„œ๋Š” ๊ฐ์ฒด๊ฐ€ ํฌํ•จํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ์ง‘์ค‘ํ•œ๋‹ค. (์ด ๊ฐ์ฒด๊ฐ€ ํฌํ•จํ•ด์•ผ ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋Š” ๋ฌด์—‡์ธ๊ฐ€?)
  • ์ด์ œ ์บก์Šํ™”๋ฅผ ์œ„ํ•ด์„œ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ธ ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ ‘๊ทผ์ž์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ˆ˜์ •์ž๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
public class Movie {
public MovieType getMovieType() {
return movieType;
}

public void setMovieType(MovieType movieType) {
this.movieType = movieType;
}

public Money getFee() {
return fee;
}

public List<DiscountCondition> getDiscountConditions() {
return Collections.unmodifiableList(discountConditions);
}

public void setDiscountConditions(List<DiscountCondition> discountConditions) {
this.discountConditions = discountConditions;
}

public Money getDiscountAmount() {
return discountAmount;
}

public void setDiscountAmount(Money discountAmount) {
this.discountAmount = discountAmount;
}

public double getDiscountPercent() {
return discountPercent;
}

public void setDiscountPercent(double discountPercent) {
this.discountPercent = discountPercent;
}
}
  • ์ด์ œ ํ• ์ธ ์กฐ๊ฑด์„ ๊ตฌํ˜„ํ•œ๋‹ค. ์˜ํ™” ์˜ˆ๋งค ๋„๋ฉ”์ธ์— ์ˆœ๋ฒˆ ์กฐ๊ฑด๊ณผ ๊ธฐ๊ฐ„ ์กฐ๊ฑด์ด ์žˆ๋‹ค.
public enum DiscountConditionType {
SEQUENCE, // ์ˆœ๋ฒˆ ์กฐ๊ฑด
PERIOD // ๊ธฐ๊ฐ„ ์กฐ๊ฑด
}
  • ํ• ์ธ ์กฐ๊ฑด์„ ๊ตฌํ˜„ํ•˜๋Š” DiscountCondition์€ ํ• ์ธ ์กฐ๊ฑด์˜ ํƒ€์ž…์„ ์ €์žฅํ•  ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜์ธ type์„ ํฌํ•จํ•œ๋‹ค.
public class DiscountCondition {
private DiscountConditionType type;

private int sequence; // ์ƒ์˜ ์ˆœ๋ฒˆ

private DayOfWeek dayOfWeek; // ์š”์ผ
private LocalTime startTime; // ์‹œ์ž‘ ์‹œ๊ฐ„
private LocalTime endTime; // ์ข…๋ฃŒ ์‹œ๊ฐ„
}
  • ์บก์Šํ™”๋ฅผ ํ†ตํ•ด ์ด ์†์„ฑ๋“ค์„ ํด๋ž˜์Šค ์™ธ๋ถ€๋กœ ๋…ธ์ถœํ•ด์„œ๋Š” ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— Movie ํด๋ž˜์Šค์ฒ˜๋Ÿผ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
public class DiscountCondition {
public DiscountConditionType getType() {
return type;
}

public void setType(DiscountConditionType type) {
this.type = type;
}

// ์ƒ๋žต...
}
  • ์ด์–ด์„œ Screening ํด๋ž˜์Šค๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค. ์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•˜๋Š”์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์บก์Šํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
public class Screening {
private Movie movie;
private int sequence;
private LocalDateTime whenScreened;

public Movie getMovie() {
return movie;
}

public void setMovie(Movie movie) {
this.movie = movie;
}

// ์ƒ๋žต...
}
  • ์˜ํ™” ์˜ˆ๋งค ์‹œ์Šคํ…œ์˜ ๋ชฉ์ ์€ ์˜ํ™”๋ฅผ ์˜ˆ๋งคํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— Reservation ํด๋ž˜์Šค๋„ ์ถ”๊ฐ€ํ•œ๋‹ค.
public class Reservation {
private Customer customer;
private Screening screening;
private Money fee;
private int audienceCount;

public Reservation(Customer customer, Screening screening, Money fee, int audienceCount) {
this.customer = customer;
this.screening = screening;
this.fee = fee;
this.audienceCount = audienceCount;
}

public Customer getCustomer() {
return customer;
}

public void setCustomer(Customer customer) {
this.customer = customer;
}

// ์ƒ๋žต...
}
  • ๋‹ค์Œ์€ Customerํด๋ž˜์Šค๋กœ ๊ณ ๊ฐ์˜ ์ •๋ณด๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
public class Customer {
private String name;
private String id;

public Customer(String name, String id) {
this.id = id;
this.name = name;
}
}

๐ŸŽˆ ์˜ํ™”๋ฅผ ์˜ˆ๋งคํ•˜์žโ€‹

  • ReservationAgency๋Š” ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค๋“ค์„ ์กฐํ•ฉํ•ด์„œ ์˜ํ™” ์˜ˆ๋งค ์ ˆ์ฐจ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.
public class ReservationAgency {
public Reservation reserve(Screening screening, Customer customer, int audienceCount) {
Movie movie = screening.getMovie();

boolean discountable = false;
// DiscountCondition์— ๋Œ€ํ•ด ๋ฃจํ”„๋ฅผ ๋Œ๋ฉด์„œ ํ• ์ธ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ
for (DiscountCondition condition : movie.getDiscountConditions()) {
if (condition.getType() == DiscountConditionType.PERIOD) {
// ๊ธฐ๊ฐ„ ์กฐ๊ฑด
} else {
// ์ˆœ๋ฒˆ ์กฐ๊ฑด
}

if (discountable) {
break;
}
}

Money fee;
if (discountable) { // ํ• ์ธ ์—ฌ๋ถ€
Money discountAmount = Money.ZERO;
// ํ• ์ธ ์ •์ฑ…์— ๋”ฐ๋ผ ์˜ˆ๋งค ์š”๊ธˆ ๊ณ„์‚ฐ
switch(movie.getMovieType()) {
case AMOUNT_DISCOUNT:
// ๊ธˆ์•ก ํ• ์ธ ์ •์ฑ…
case PERCENT_DISCOUNT:
// ํ• ์ธ ๋น„์œจ
case NONE_DISCOUNT:
// ํ• ์ธ ์ •์ฑ…์ด ์ ์šฉ x
}

fee = movie.getFee().minus(discountAmount);
} else {
fee = movie.getFee();
}

return new Reservation(customer, screening, fee, audienceCount);
}
}

๐Ÿ“š ์„ค๊ณ„ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„โ€‹

๐ŸŽˆ ์บก์Šํ™”โ€‹

  • ์ƒํƒœ์™€ ํ–‰๋™์„ ํ•˜๋‚˜์˜ ๊ฐ์ฒด ์•ˆ์— ๋ชจ์œผ๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๊ฐ์ถ”๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค. (์—ฌ๊ธฐ์„œ ๊ตฌํ˜„์ด๋ž€ ๋‚˜์ค‘์— ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ์–ด๋–ค ๊ฒƒ)
  • ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๋ถ€๋ถ„์€ ๊ตฌํ˜„, ์ƒ๋Œ€์ ์œผ๋กœ ์•ˆ์ •์ ์ธ ๋ถ€๋ถ„์„ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.
  • ์บก์Šํ™”๋Š” ์™ธ๋ถ€์—์„œ ์•Œ ํ•„์š”๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„์„ ๊ฐ์ถค์œผ๋กœ์จ ๋Œ€์ƒ์„ ๋‹จ์ˆœํ™”ํ•˜๋Š” ์ถ”์ƒํ™”์˜ ํ•œ ์ข…๋ฅ˜์ด๋‹ค. (์•ˆ์ •์ ์ธ ์ธํ„ฐํŽ˜์ด์Šค ๋’ค๋กœ ์บก์Šํ™”ํ•œ๋‹ค.)
  • ์บก์Šํ™”๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ ๋Š” ๋ถˆ์•ˆ์ •ํ•œ ๋ถ€๋ถ„๊ณผ ์•ˆ์ •์ ์ธ ๋ถ€๋ถ„์„ ๋ถ„๋ฆฌํ•ด์„œ ๋ณ€๊ฒฝ์˜ ์˜ํ–ฅ์„ ํ†ต์ œํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์บก์Šํ™”๋ž€ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์€ ๋ถ€๋ถ„์„ ๊ฐ์ฒด ๋‚ด๋ถ€๋กœ ์ˆจ๊ธฐ๋Š” ์ถ”์ƒํ™” ๊ธฐ๋ฒ•์ด๋‹ค.

๐ŸŽˆ ์‘์ง‘๋„์™€ ๊ฒฐํ•ฉ๋„โ€‹

  • ์‘์ง‘๋„๋Š” ๋ชจ๋“ˆ์— ํฌํ•จ๋œ ๋‚ด๋ถ€ ์š”์†Œ๋“ค์ด ์—ฐ๊ด€๋ผ ์žˆ๋Š” ์ •๋„๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋ชจ๋“ˆ ๋‚ด์˜ ์š”์†Œ๋“ค์ด ํ•˜๋‚˜์˜ ๋ชฉ์ ์„ ์œ„ํ•ด ๊ธด๋ฐ€ํ•˜๊ฒŒ ํ˜‘๋ ฅํ•œ๋‹ค๋ฉด ๊ทธ ๋ชจ๋“ˆ์€ ๋†’์€ ์€์ง‘๋„๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ๊ฒนํ•ฉ๋„๋Š” ์˜์กด์„ฑ์˜ ์ •๋„๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ ๋‹ค๋ฅธ ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ์ง€์‹์„ ๊ฐ–๊ณ  ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ฒ™๋„์ด๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ๋„ˆ๋ฌด ์ž์„ธํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋†’์€ ๊ฒฐํ•ฉ๋„๋ฅผ ๊ฐ€์ง„๋‹ค.
  • ๋†’์€ ์€์ง‘๋„์™€ ๋‚ฎ์€ ๊ฒฐํ•ฉ๋„๋ฅผ ๊ฐ€์ง„ ์„ค๊ณ„๋ฅผ ์ถ”๊ตฌํ•ด์•ผ ํ•˜๋Š” ์ด์œ ๋Š” ์„ค๊ณ„๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋ณ€๊ฒฝ์˜ ๊ด€์ ์—์„œ ์‘์ง‘๋„๋ž€ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•  ๋•Œ ๋ชจ๋“ˆ ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ณ€๊ฒฝ์˜ ์ •๋„๋กœ ์ธก์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. (ํ•˜๋‚˜์˜ ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•ด ๋ชจ๋“ˆ ์ „์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ๊ฒฐํ•ฉ๋„๋Š” ๋†’๊ณ , ํ•˜๋‚˜์˜ ๋ณ€๊ฒฝ์— ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ๋งŒ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ๊ฒฐํ•ฉ๋„๋Š” ๋‚ฎ์€ ๊ฒƒ์ด๋‹ค.)
  • ์บก์Šํ™”๋ฅผ ์ง€ํ‚ค๋ฉด ๋ชจ๋“ˆ ์•ˆ์˜ ์‘์ง‘๋„๋Š” ๋†’์•„์ง€๊ณ  ๋ชจ๋“ˆ ์‚ฌ์ด์˜ ๊ฒฐํ•ฉ๋„๋Š” ๋‚ฎ์•„์ง„๋‹ค.

๐Ÿ“š ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์˜ํ™” ์˜ˆ๋งค ์‹œ์Šคํ…œ์˜ ๋ฌธ์ œ์ โ€‹

  • Movie์˜ˆ์ œ์˜ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„๋Š” ์ฑ…์ž„ ์ค‘์‹ฌ ์„ค๊ณ„์™€ ๊ธฐ๋Šฅ์ ์œผ๋กœ๋Š” ์™„์ „ํžˆ ๋™์ผํ•˜์ง€๋งŒ ์„ค๊ณ„ ๊ด€์ ์—์„œ๋Š” ์™„์ „ํžˆ ๋‹ค๋ฅด๋‹ค.
  • ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด์ ์€ ์บก์Šํ™”๋ฅผ ๋‹ค๋ฃจ๋Š” ๋ฐฉ์‹์ด๋‹ค. ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์€ ์บก์Šํ™”๋ฅผ ์œ„๋ฐ˜ํ•˜๊ณ  ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ผ๋ถ€๋กœ ๋งŒ๋“ ๋‹ค.
  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„์˜ ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ์ ์€ ์„ธ ๊ฐ€์ง€๋กœ ์บก์Šํ™” ์œ„๋ฐ˜, ๋†’์€ ๊ฒฐํ•ฉ๋„, ๋‚ฎ์€ ์‘์ง‘๋„์ด๋‹ค.

๐ŸŽˆ ์บก์Šํ™” ์œ„๋ฐ˜โ€‹

  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์œผ๋กœ ์„ค๊ณ„ํ•œ Movie ํด๋ž˜์Šค๋Š” ์˜ค์ง ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ ‘๊ทผ์ž์™€ ์ˆ˜์ •์ž ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด ๋‚ด๋ถ€์˜ ์ƒํƒœ์— ๋Œ€ํ•œ ์–ด๋–ค ์ •๋ณด๋„ ์บก์Šํ™”ํ•˜์ง€ ๋ชปํ•œ๋‹ค.
public class Movie {
// Movie ๋‚ด๋ถ€์— Money ํƒ€์ž…์˜ fee๋ผ๋Š” ์ด๋ฆ„์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„
// ํผ๋ธ”๋ฆญ ์ธํ„ฐํŽ˜์ด์Šค์— ๋…ธ๊ณจ์ ์œผ๋กœ ๋“œ๋Ÿฌ๋‚ธ๋‹ค.
private Money fee;

public Money getFee() {
return fee;
}

public void setFee(Money fee) {
this.fee = fee;
}
}
  • ์ด๋Ÿฌํ•œ ๊ทผ๋ณธ์ ์ธ ์›์ธ์€ ๊ฐ์ฒด๊ฐ€ ์ˆ˜ํ–‰ํ•  ์ฑ…์ž„์ด ์•„๋‹ˆ๋ผ ๋‚ด๋ถ€์— ์ €์žฅํ•  ๋ฐ์ดํ„ฐ์— ์ดˆ์ ์„ ๋งž์ท„๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์ž์™€ ์ˆ˜์ •์ž์— ๊ณผ๋„ํ•˜๊ฒŒ ์˜์กดํ•˜๋Š” ์„ค๊ณ„ ๋ฐฉ์‹์€ ์ถ”์ธก์— ์˜ํ•œ ์„ค๊ณ„ ์ „๋žต์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ์ด ์ „๋žต์€ ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ๋  ํ˜‘๋ ฅ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด๊ฐ€ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๋Š” ๋ง‰์—ฐํ•œ ์ถ”์ธก์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค๊ณ„๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

๐ŸŽˆ ๋†’์€ ๊ฒฐํ•ฉ๋„โ€‹

  • ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ๋ณ€๊ฒฝํ–ˆ์Œ์—๋„ ์ด ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๋“ค๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝํ•ด์•ผ ํ•œ๋‹ค.
public class ReservationAgency {
public Reservation reserve(Screening screening, Customer customer, int audienceCount) {
// ...
Money fee;
if (discountable) {
// ...
fee = movie.getFee().minus(discountAmount);
} else {
fee = movie.getFee();
}

return new Reservation(customer, screening, fee, audienceCount);
}
}
  • ๋งŒ์•ฝ ์œ„ ์ฝ”๋“œ์—์„œ fee์˜ ํƒ€์ž…์„ ๋ณ€๊ฒฝํ•œ๋‹ค๋ฉด ์ด๋ฅผ ์œ„ํ•ด์„œ getFee ๋ฉ”์„œ๋“œ์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  getFee๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ReservationAgency์˜ ๊ตฌํ˜„๋„ ๋ณ€๊ฒฝ๋œ ํƒ€์ž…์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„๋Š” ๊ฐ์ฒด์˜ ์บก์Šํ™”๋ฅผ ์•ฝํ™”์‹œํ‚ค๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ์ฒด์˜ ๊ตฌํ˜„์— ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋œ๋‹ค.
  • ReservationAgency๊ฐ€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์— ์˜์กดํ•˜๊ณ  ์žˆ๋‹ค. DiscountCondition์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ReservationAgency๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„๋Š” ์ „์ฒด ์‹œ์Šคํ…œ์„ ํ•˜๋‚˜์˜ ๊ฑฐ๋Œ€ํ•œ ์˜์กด์„ฑ ๋ฉ์–ด๋ฆฌ๋กœ ๋งŒ๋“ค์–ด ๋ฒ„๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋–ค ๋ณ€๊ฒฝ์ด๋ผ๋„ ์ผ๋‹จ ๋ฐœ์ƒํ•˜๊ณ  ๋‚˜๋ฉด ์‹œ์Šคํ…œ ์ „์ฒด๊ฐ€ ์š”ํ†ต์น  ์ˆ˜๋ฐ–์— ์—†๋‹ค.

๐ŸŽˆ ๋‚ฎ์€ ์‘์ง‘๋„โ€‹

  • ReservationAgency๊ฐ€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆ˜์ •์‚ฌํ•ญ์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ์— ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
    • ํ• ์ธ ์ •์ฑ…์ด ์ถ”๊ฐ€๋  ๊ฒฝ์šฐ
    • ํ• ์ธ ์ •์ฑ…๋ณ„๋กœ ํ• ์ธ ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ
    • ํ• ์ธ ์กฐ๊ฑด์ด ์ถ”๊ฐ€๋  ๊ฒฝ์šฐ
    • ํ• ์ธ ์กฐ๊ฑด๋ณ„๋กœ ํ• ์ธ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ
    • ์˜ˆ๋ฉ” ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ
  • ๋‚ฎ์€ ์‘์ง‘๋„๋Š” ๋‘ ๊ฐ€์ง€ ์ธก๋ฉด์—์„œ ์„ค๊ณ„์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚จ๋‹ค.
    • ๋ณ€๊ฒฝ์˜ ์ด์œ ๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์ฝ”๋“œ๋“ค์„ ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ ์•ˆ์— ๋ญ‰์ณ๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ€๊ฒฝ๊ณผ ์•„๋ฌด ์ƒ๊ด€์ด ์—†๋Š” ์ฝ”๋“œ๋“ค์ด ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค.
    • ํ•˜๋‚˜์˜ ์š”๊ตฌ์‚ฌํ•ญ ๋ณ€๊ฒฝ์„ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ๋™์‹œ์— ์—ฌ๋Ÿฌ ๋ชจ๋“ˆ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

๋‹จ์ผ ์ฑ…์ž„ ์›์น™(SRP)

  • ๋ชจ๋“ˆ์˜ ์‘์ง‘๋„๊ฐ€ ๋ณ€๊ฒฝ๊ณผ ์—ฐ๊ด€์ด ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์ด ๋‚˜์™”๋‹ค.
  • ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์€ ํด๋ž˜์Šค๋Š” ๋‹จ ํ•œ ๊ฐ€์ง€์˜ ๋ณ€๊ฒฝ ์ด์œ ๋งŒ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค.

๐Ÿ“š ์ž์œจ์ ์ธ ๊ฐ์ฒด๋ฅผ ํ–ฅํ•ดโ€‹

๐ŸŽˆ ์บก์Šํ™”๋ฅผ ์ง€์ผœ๋ผโ€‹

  • ๊ฐ์ฒด๋Š” ์Šค์Šค๋กœ์˜ ์ƒํƒœ๋ฅผ ์ฑ…์ž„์ ธ์•ผ ํ•˜๊ณ  ์™ธ๋ถ€์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์— ์ •์˜๋œ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  • ์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ๋ฉ”์„œ๋“œ๋Š” ์ ‘๊ทผ์ž๋‚˜ ์ˆ˜์ •์ž๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐ์ฒด์—๊ฒŒ ์˜๋ฏธ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋Š” ๊ฐ์ฒด๊ฐ€ ์ฑ…์ž„์ ธ์•ผ ํ•˜๋Š” ๋ฌด์–ธ๊ฐ€๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.
  • ์ ‘๊ทผ์ž์™€ ์ˆ˜์ •์ž๋ฅผ ์‚ฌ์šฉํ•œ ๋ฉ”์„œ๋“œ์˜ ๋ฌธ์ œ์ ์€ ์ฝ”๋“œ ์ค‘๋ณต์ด ๋ฐœ์ƒํ•  ํ™•๋ฅ ์ด ๋†’๋‹ค. ๋˜ํ•œ ๋ณ€๊ฒฝ์— ์ทจ์•ฝํ•˜๋‹ค. getBottom์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๊ณณ์—์„œ ์ˆ˜์ •์ด ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค.
  • ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์บก์Šํ™”๋ฅผ ๊ฐ•ํ™”์‹œํ‚ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ฐ์ฒด๊ฐ€ ์ž๊ธฐ ์Šค์Šค๋กœ ์ฑ…์ž„์„ ์ง€๊ฒŒ ๋ง์ด๋‹ค.

๐ŸŽˆ ์Šค์Šค๋กœ ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ…์ž„์ง€๋Š” ๊ฐ์ฒดโ€‹

  • ์ƒํƒœ์™€ ํ–‰๋™์„ ๊ฐ์ฒด๋ผ๋Š” ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ๋Š” ์ด์œ ๋Š” ๊ฐ์ฒด ์Šค์Šค๋กœ ์ž์‹ ์˜ ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค.
  • ๊ฐ์ฒด ๋‚ด๋ถ€์— ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ณด๋‹ค ๊ฐ์ฒด๊ฐ€ ํ˜‘๋ ฅ์— ์ฐธ์—ฌํ•˜๋ฉด์„œ ์ˆ˜ํ–‰ํ•  ์ฑ…์ž„์„ ์ •์˜ํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜์ด ๋” ์ค‘์š”ํ•˜๋‹ค.
    • ์ด ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•˜๋Š”๊ฐ€?
    • ์ด ๊ฐ์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜์€ ๋ฌด์—‡์ธ๊ฐ€?
  • ๋‘ ์งˆ๋ฌธ์„ ์กฐํ•ฉํ•˜๋ฉด ๊ฐ์ฒด์˜ ๋‚ด๋ถ€ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์ €์žฅ๋œ ์ƒํƒœ์— ๋Œ€ํ•ด ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ์˜คํผ๋ ˆ์ด์…˜์˜ ์ง‘ํ•ฉ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ ํƒ€์ž…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
  • ์˜ํ™” ์˜ˆ๋งค ์‹œ์Šคํ…œ์˜ ReservationAgency๋กœ ์ƒˆ์–ด๋‚˜๊ฐ„ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ฑ…์ž„์„ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋กœ ์˜ฎ๊ฒจ๋ณธ๋‹ค.
  • ํ• ์ธ ์กฐ๊ฑด์„ ํ‘œํ˜„ํ•˜๋Š” DiscountCondition๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์งˆ๋ฌธ์ธ ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ง€๋ฅผ ๋ฌป๋Š”๊ฑด ์•ž์—์„œ ๊ฒฐ์ •ํ•ด ๋†“์•˜๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ์งˆ๋ฌธ์€ ์ด ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์˜คํฌ๋ ˆ์ด์…˜์ด ๋ฌด์—‡์ธ๊ฐ€๋ฅผ ๋ฌป๋Š” ๊ฒƒ์ด๋‹ค. ํ• ์ธ ์กฐ๊ฑด์—๋Š” ์ˆœ๋ฒˆ ์กฐ๊ฑด๊ณผ ๊ธฐ๊ฐ„ ์กฐ๊ฑด์˜ ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์กด์žฌํ•˜๊ณ  DiscountCondition์˜ ์ˆœ๋ฒˆ ์กฐ๊ฑด์ผ ๊ฒฝ์šฐ์—๋Š” sequence๋ฅผ ์ด์šฉํ•˜๊ณ  ๊ธฐ๊ฐ„ ์กฐ๊ฑด์ผ ๊ฒฝ์šฐ์—๋Š” dayOfWeek, startTime, endTime์„ ์ด์šฉํ•ด ํ• ์ธ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ๋‘ ๊ฐœ์˜ isDiscountable์ด ํ•„์š”ํ•  ๊ฒƒ์ด๊ณ  ๊ฐ isDiscountable ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ type์˜ ๊ฐ’์„ ์ด์šฉํ•ด ํ˜„์žฌ์˜ ํ• ์ธ ์กฐ๊ฑด ํƒ€์ž…์— ๋งž๋Š” ์ ์ ˆํ•œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋๋Š”์ง€ ํŒ๋‹จํ•œ๋‹ค.
public class DiscountCondition {
// ๋ฐ์ดํ„ฐ ์ƒ๋žต..

public DiscountConditionType getType() {
return type;
}

public boolean isDiscountable(DayOfWeek dayOfWeek, LocalTime time) {
if (type != DiscountConditionType.PERIOD) {
throw new IllegalArgumentException();
}

return this.dayOfWeek.equal(dayOfWeek) &&
this.startTime.compareTo(time) <= 0 &&
this.endTime.compareTo(time) >= 0;
}

public boolean isDiscountable(int sequence) {
if (type != DiscountConditionType.SEQUENCE) {
throw new IllegalArgumentException();
}

return this.sequence == sequence;
}
}
  • ๋‹ค์Œ์€ Movie๋ฅผ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์ฒซ ๋ฒˆ์งธ ์งˆ๋ฌธ์€ ์ด๋ฏธ ๊ฒฐ์ •ํ–ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ์งˆ๋ฌธ์€ Movie๋Š” ์˜ํ™” ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜๊ณผ ํ• ์ธ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜์ด ํ•„์š”ํ•˜๋‹ค. ํ• ์ธ ์ •์ฑ…์€ ๊ธˆ์•ก ํ• ์ธ, ๋น„์œจ ํ• ์ธ, ํ• ์ธ ๋ฏธ์ ์šฉ์˜ ์„ธ ๊ฐ€์ง€ ํƒ€์ž…์ด ์žˆ๋‹ค. ๋•Œ๋ฌธ์— ํ• ์ธ ์ •์ฑ…์˜ ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” getMovieType ๋ฉ”์„œ๋“œ์™€ ์ •์ฑ…๋ณ„๋กœ ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•˜๋Š” ์„ธ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.
public class Movie {
// ๋ฐ์ดํ„ฐ ์ƒ๋žต..

public MovieType getMovieType() {
return movieType;
}

public Money calculateAmountDiscountedFee() {
if (movieType != MovieType.AMOUNT_DISCOUNT) {
throw new IllegalArgumentException();
}

return fee.minus(discountAmount);
}

// ๋‹ค ๋น„์Šท.. ์ƒ๋žต..
}
  • Movie๋Š” DiscountCondition์˜ ๋ชฉ๋ก์„ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ• ์ธ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๋Š” ์˜คํผ๋ ˆ์ด์…˜ ์—ญ์‹œ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค.
public class Movie {
public boolean isDiscountable(LocalDateTime whenScreened, int sequence) {
for (DiscountCondition condition : discountConditions) {
// ๊ธฐ๊ฐ„ ์กฐ๊ฑด ๊ฒ€์ฆ
if (condition.getType() == DiscountConditionType.PERIOD) {
if (condition.isDiscountable(whenScreened.getDayOfWeek(), whenScreened.toLocalTime())) {
return true;
}
} else {
// ์ˆœ๋ฒˆ ์กฐ๊ฑด ๊ฒ€์ฆ
if (condition.isDiscountable(sequence)) {
return false;
}
}
}

return false;
}
}
  • Screening ํด๋ž˜์Šค๋„ ๋‘ ์งˆ๋ฌธ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๋ฉฐ ๊ตฌํ˜„ํ•œ๋‹ค.
public class Screening {
// ์ƒ๋žต..

public Money calculateFee(int audienceCount) {
switch (movie.getMovieType()) {
case AMOUNT_DISCOUNT:
// ...
case PERCENT_DISCOUNT:
// ...
case NONE_DISCOUNT:
// ...
}
}
}
  • ReservationAgency๋Š” Screening์˜ calculateFee ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์˜ˆ๋งค ์š”๊ธˆ์„ ๊ณ„์‚ฐํ•œ ํ›„ ๊ณ„์‚ฐ๋œ ์š”๊ธˆ์„ ์ด์šฉํ•ด Reservation์„ ์ƒ์„ฑํ•œ๋‹ค.
public class ReservationAgency {
public Reservation reserve(Screening screening, Customer customer, int audienceCount) {
Money fee = screening.calculateFee(audienceCount);
return new Reservation(customer, screening, fee, audienceCount);
}
}
  • ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ๋” ๋ฉด๋ฐ€ํ•˜๊ฒŒ ์บก์Šํ™”ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ข€๋” ๊ฐœ์„ ๋˜์—ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ์„ค๊ณ„์—์„œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ์ฒด ์Šค์Šค๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ๊ฐ์ฒด๋“ค์€ ์Šค์Šค๋กœ๋ฅผ ์ฑ…์ž„์ง„๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“š ํ•˜์ง€๋งŒใ„ด ์—ฌ์ „ํžˆ ๋ถ€์กฑํ•˜๋‹ค.โ€‹

  • ๋‘ ๋ฒˆ์งธ ์„ค๊ณ„ ์—ญ์‹œ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„ ๋ฐฉ์‹์— ์†ํ•œ๋‹ค.

๐ŸŽˆ ์บก์Šํ™” ์œ„๋ฐ˜โ€‹

  • ์ˆ˜์ •๋œ ๊ฐ์ฒด๋“ค์€ ์ž๊ธฐ ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์Šค์Šค๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. DiscountCondition์€ ์ž๊ธฐ ์ž์‹ ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด ํ• ์ธ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ์Šค์Šค๋กœ ํŒ๋‹จํ•œ๋‹ค.
public class DiscountCondition {
private DiscountConditionType type;
private int sequence;
private DayOfWeek dayOfWeek;
private LocalTime startTime;
private LocalTime endTime;

public DiscountConditionType getType() { }

public boolean isDiscountable(DayOfWeek dayOfWeek, LocalTime time) { }

public boolean isDiscountable(int sequence) { }
}
  • ํ•˜์ง€๋งŒ DiscountCondition์— ๊ตฌํ˜„๋œ ๋‘ ๊ฐœ์˜ isDiscountable ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด DayOfWeek ํƒ€์ž…์˜ ์š”์ผ ์ •๋ณด์™€ LocalTime ํƒ€์ž…์˜ ์‹œ๊ฐ„ ์ •๋ณด๊ฐ€ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ํฌํ•จ๋ผ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • Movie๋„ ์—ญ์‹œ ์บก์Šํ™”๊ฐ€ ๋ถ€์กฑํ•˜๋‹ค. ๋‚ด๋ถ€ ๊ตฌํ˜„์„ ์ธํ„ฐํŽ˜์ด์Šค์— ๋…ธ์ถœ์‹œํ‚ค๊ณ  ์žˆ๋‹ค. calculateAmountDiscountedFee, calculatePercentDiscountedFee, calculateNoneDiscountedFee์ด๋ผ๋Š” ์„ธ ๊ฐœ์˜ ๋ฉ”์„œ๋“œ๋Š” ํ• ์ธ ์ •์ฑ…์—๋Š” ๊ธˆ์•ก ํ• ์ธ ์ •์ฑ…, ๋น„์œจ ํ• ์ธ ์ •์ฑ…, ๋ฏธ์ ์šฉ์˜ ์„ธ ๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋“œ๋Ÿฌ๋‚ด๊ณ  ์žˆ๋‹ค.

๐ŸŽˆ ๋†’์€ ๊ฒฐํ•ฉ๋„โ€‹

  • ์บก์Šํ™” ์œ„๋ฐ˜์œผ๋กœ ์ธํ•ด DiscountCondition์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์ด ์™ธ๋ถ€๋กœ ๋…ธ์ถœ๋๊ธฐ ๋•Œ๋ฌธ์— Movie์™€ DiscountCondition ์‚ฌ์ด์˜ ๊ฒฐํ•ฉ๋„๋Š” ๋†’์„ ์ˆ˜๋ฐ–์— ์—†๋‹ค.
public class Movie {
public boolean isDiscountable(LocalDateTime whenScreened, int sequence) {
for (DiscountCondition condition : discountConditions) {
if (condition.getType() == DiscountConditionType.PERIOD) {
if (condition.isDiscountable(whenScreened.getDayOfWeek(), whenScreened.toLocalTime())) {
return true;
}
} else {
if (condition.isDiscountable(sequence)) {
return false;
}
}
}

return false;
}
}
  • DiscountCondition์˜ ๊ธฐ๊ฐ„ ํ• ์ธ ์กฐ๊ฑด์˜ ๋ช…์นญ์ด PERIOD์—์„œ ๋‹ค๋ฅธ ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด Movie๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.
  • DiscountCondition์˜ ์ข…๋ฅ˜๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋œ๋‹ค๋ฉด if ~ else๊ตฌ๋ฌธ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“š ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„์˜ ๋ฌธ์ œ์ โ€‹

  • ๋‘ ๋ฒˆ์งธ ์„ค๊ณ„๊ฐ€ ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜์ง€ ๋ชปํ•œ ์ด์œ ๋Š” ์บก์Šํ™”๋ฅผ ์œ„๋ฐ˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„๊ฐ€ ๋ณ€๊ฒฝ์— ์ทจ์•ฝํ•œ ์ด์œ ๋Š” ๋‘ ๊ฐ€์ง€๋‹ค.
    • ๋ณธ์งˆ์ ์œผ๋กœ ๋„ˆ๋ฌด ์ด๋ฅธ ์‹œ๊ธฐ์— ๋ฐ์ดํ„ฐ์— ๊ด€ํ•ด ๊ฒฐ์ •ํ•˜๋„๋ก ๊ฐ•์š”ํ•œ๋‹ค.
    • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„์—์„œ๋Š” ํ˜‘๋ ฅ์ด๋ผ๋Š” ๋ฌธ๋งฅ์„ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  ๊ฐ์ฒด๋ฅผ ๊ณ ๋ฆฝ์‹œํ‚จ ์ฑ„ ์˜คํผ๋ ˆ์ด์…˜์„ ๊ฒฐ์ •ํ•œ๋‹ค.

๐ŸŽˆ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„์˜ ๊ฐ์ฒด์˜ ํ–‰๋™๋ณด๋‹ค๋Š” ์ƒํƒœ์— ์ดˆ์ ์„ ๋งž์ถ˜๋‹ค.โ€‹

  • ๋ฐ์ดํ„ฐ์— ์ดˆ์ ์ด ๋งž์ถฐ์ ธ ์žˆ๋‹ค๋ฉด ๋งŒ์กฑ์Šค๋Ÿฌ์šด ์บก์Šํ™”๋ฅผ ์–ป๊ธฐ ์–ด๋ ต๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋จผ์ € ๊ฒฐ์ •ํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์˜คํผ๋ ˆ์ด์…˜์„ ๋‚˜์ค‘์— ๊ฒฐ์ •ํ•˜๋Š” ๋ฐฉ์‹์€ ๋ฐ์ดํ„ฐ์— ๊ด€ํ•œ ์ง€์‹์ด ๊ฐ์ฒด์˜ ์ธํ„ฐํŽ˜์ด์Šค์— ๊ณ ์Šค๋ž€ํžˆ ๋“œ๋Ÿฌ๋‚˜๊ฒŒ ๋œ๋‹ค.
  • ๊ฒฐ๋ก ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ์˜ ์„ค๊ณ„๋Š” ๋„ˆ๋ฌด ์ด๋ฅธ ์‹œ๊ธฐ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋Œ€ํ•ด ๊ณ ๋ฏผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์บก์Šํ™”์— ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค.

๐ŸŽˆ ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„๋Š” ๊ฐ์ฒด๋ฅผ ๊ณ ๋ฆฝ์‹œํ‚จ ์ฑ„ ์˜คํผ๋ ˆ์ด์…˜์„ ์ •์˜ํ•˜๋„๋ก ๋งŒ๋“ ๋‹คโ€‹

  • ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ ์„ค๊ณ„์—์„œ ์ดˆ์ ์€ ๊ฐ์ฒด์˜ ์™ธ๋ถ€๊ฐ€ ์•„๋‹ˆ๋ผ ๋‚ด๋ถ€๋กœ ํ–ฅํ•œ๋‹ค.
  • ์‹คํ–‰ ๋ฌธ๋งฅ์— ๋Œ€ํ•œ ๊นŠ์ด ์žˆ๋Š” ๊ณ ๋ฏผ ์—†์ด ๊ฐ์ฒด๊ฐ€ ๊ด€๋ฆฌํ•  ๋ฐ์ดํ„ฐ์˜ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ๋จผ์ € ๊ฒฐ์ •ํ•œ๋‹ค.