ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,89 @@
+package christmas.service;
+
+import christmas.constant.Month;
+import christmas.util.Printer;
+import christmas.domain.ReservationInfo;
+
+public class PlannerServiceImpl implements PlannerService {
+
+    private final ReservationInfo reservationInfo = new ReservationInfo();
+
+    @Override
+    public void makeReservationDate(String date) {
+
+        reservationInfo.makeReservation(date);
+    }
+
+    @Override
+    public void reservationMenu(String orderMenu) {
+
+        reservationInfo.submitOrder(orderMenu);
+    }
+
+    @Override
+    public String printReservationPaper() {
+
+        StringBuilder paper = new StringBuilder();
+        paper.append(printEventMessage())
+                .append(printOrderMenu())
+                .append(printOrderPrice())
+                .append(printGift())
+                .append(printBenefit())
+                .append(printBenefitPrice())
+                .append(printExpectedPayment())
+                .append(printEventBadge());
+
+        return paper.toString();
+    }
+
+    @Override
+    public String printEventMessage() {
+
+        return Printer.EVENT_INFO_MESSAGE.
+                printEventMessage(Month.DECEMBER.getMonth(),
+                        reservationInfo.getReservationDate());
+    }
+
+    @Override
+    public String printOrderMenu() {
+
+        return Printer.ORDER_MENU.print(reservationInfo.getOrderMenu());
+    }
+
+    @Override
+    public String printOrderPrice() {
+
+        return Printer.ORDER_PRICE.print(reservationInfo.getOrderPrice());
+    }
+
+    @Override
+    public String printGift() {
+
+        return Printer.GIFT.print(reservationInfo.getGiftInfo());
+    }
+
+    @Override
+    public String printBenefit() {
+
+        return Printer.BENEFIT.print(reservationInfo.getBenefitInfo());
+    }
+
+    @Override
+    public String printBenefitPrice() {
+
+        return Printer.BENEFIT_PRICE.print(reservationInfo.getBenefitPrice());
+    }
+
+    @Override
+    public String printExpectedPayment() {
+
+        return Printer.EXPECTED_PRICE.print(reservationInfo.getExpectedPayment());
+    }
+
+    @Override
+    public String printEventBadge() {
+
+        return Printer.EVENT_BADGE.printEventBadge(Month.DECEMBER.getMonth(),
+                reservationInfo.getEventBadgeInfo());
+    }
+}

리뷰: 인터페이스를 만들고, 구현하는 방식 확장성있고 좋은것 같네요👍
@@ -0,0 +1,30 @@
+package christmas.view;
+
+import camp.nextstep.edu.missionutils.Console;
+import christmas.controller.PlannerController;
+
+public class InputView {
+
+    private final PlannerController plannerController;
+
+    InputView(PlannerController plannerController) {
+
+        this.plannerController = plannerController;
+    }
+    public void enterVisitDate(){
+
+        System.out.println("안녕하세요! 우테코 식당 12월 이벤트 플래너입니다.");
+        System.out.println("12월 중 식당 예상 방문 날짜는 언제인가요? (숫자만 입력해 주세요!)");
+
+        String date = Console.readLine();
+        plannerController.setReservationDate(date);
+    }
+
+    public void enterOrderMenu(){
+
+        System.out.println("주문하실 메뉴를 메뉴와 개수를 알려 주세요. (e.g. 해산물파스타-2,레드와인-1,초코케이크-1)");
+
+        String orderMenu = Console.readLine();
+        plannerController.setOrderMenu(orderMenu);
+    }
+}

리뷰: system.out.println과 같이 반복되는 로직들도 printmessage( )같이 새롭게 정의해서 만들면 좋을것 같아요
@@ -0,0 +1,24 @@
+package christmas.controller;
+
+import christmas.service.PlannerService;
+import christmas.service.PlannerServiceImpl;
+
+public class PlannerController {
+
+    private final PlannerService plannerService = new PlannerServiceImpl();
+
+    public void setReservationDate(String date) {
+
+        plannerService.makeReservationDate(date);
+    }
+
+    public void setOrderMenu(String orderMenu) {
+
+        plannerService.reservationMenu(orderMenu);
+    }
+
+    public String printReservationPaper() {
+
+        return plannerService.printReservationPaper();
+    }
+}

리뷰: 이 부분은 그냥 세팅 해준다는 의미에서 이렇게 했는데, 다른 이름 생각해봐야겠네요
@@ -0,0 +1,47 @@
+package christmas.domain;
+
+import java.util.Arrays;
+
+public enum Menu {
+
+    MUSHROOM_SOUP("양송이수프", 6000),
+    TAPAS("타파스", 5500),
+    CAESAR_SALAD("시저샐러드", 8000),
+    T_BONE_STAKE("티본스테이크", 55000),
+    BBQ_RIBS("바비큐립", 54000),
+    SEAFOOD_PASTA("해산물파스타", 35000),
+    CHRISTMAS_PASTA("크리스마스파스타", 25000),
+    CHOCOLATE_CAKE("초코케이크", 15000),
+    ICE_CREAM("아이스크림", 5000),
+    ZERO_COKE("제로콜라", 3000),
+    RED_WINE("레드와인", 60000),
+    CHAMPAGNE("샴페인", 25000),
+    EMPTY("없음", 0);
+
+    private String menuName;
+    private int price;
+
+    private Menu(String menuName, int price) {
+
+        this.menuName = menuName;
+        this.price = price;
+    }
+
+    public static Menu findMenu(String menuName) {
+
+        for(Menu menu : Menu.values()) {
+            if(menu.getMenuName().equals(menuName)) {
+                return menu;
+            }
+        }
+        return Menu.EMPTY;
+    }
+
+    public String getMenuName() {
+        return menuName;
+    }
+
+    public int getPrice() {
+        return price;
+    }
+}

리뷰: 이 부분은 MenuGroup이라는 클래스에서 Menu들을 리스트로 받아오게 처리를 했기 때문에 그렇습니다.
그런데 다른 분들 코드를 보니 Menu에 MenuType을 지정을 해놓는게 꺼내오는 로직 짜기는 편한 것 같더라구요
@@ -0,0 +1,92 @@
+package christmas.domain;
+
+import christmas.constant.*;
+
+public class ReservationInfo {
+
+    private static final String LINE_SEPARATOR = System.lineSeparator();
+    private String date;
+    private Order order;
+    private Benefit benefit;
+
+    public void makeReservation(String date) {
+
+        this.date = date;
+        int parseDate = parseDate(date);
+        validateDateRange(parseDate);
+    }
+
+    public void submitOrder(String orderMenu) {
+
+        order = new Order(orderMenu);
+        benefit = new Benefit();
+    }
+
+    private int parseDate(String date) {
+
+        try {
+
+            return Integer.parseInt(date);
+
+        }catch (Exception e){
+
+            throw new IllegalArgumentException(ErrorMessage.DATE_FORMAT_ERROR_MESSAGE.name());
+        }
+    }
+    private void validateDateRange(int date) {
+
+        if(Month.DECEMBER.getFirstDay() > date ||
+                Month.DECEMBER.getLastDay() < date) {
+
+            throw new IllegalArgumentException(ErrorMessage.DATE_RANGE_ERROR_MESSAGE.name());
+        }
+    }
+
+    public String getReservationDate() {
+
+        return date;
+    }
+
+    public String getOrderMenu() {
+
+        return order.createOrderMenuInfo();
+    }
+
+    public String getOrderPrice() {
+
+        return Price.df.format(order.calculateOrderPrice())+Price.WON+LINE_SEPARATOR;
+    }
+
+    public String getGiftInfo() {
+
+        return benefit.getGiftInfo(order.calculateOrderPrice());
+    }
+
+    public String getBenefitInfo() {
+
+        int orderPrice = order.calculateOrderPrice();
+        boolean isLessThanMinimumPrice = orderPrice < Price.MINIMUM_PRICE_APPLY_EVENT;
+        String benefitInfo = benefit.getBenefitInfo(date, order.getOrders());
+
+        if(isLessThanMinimumPrice||benefitInfo.equals("")) {
+
+            return BenefitMessage.NO_BENEFIT + LINE_SEPARATOR;
+        }
+        return benefitInfo;
+    }
+
+    public String getBenefitPrice() {
+
+        return benefit.getBenefitPrice(order.calculateOrderPrice());
+    }
+
+    public String getExpectedPayment() {
+
+        return benefit.getExpectedPayment(order.calculateOrderPrice());
+    }
+
+    public String getEventBadgeInfo() {
+
+        return benefit.getBadgeInfo();
+    }
+}

리뷰: 네 이부분은 미처 보지 못한 것 같습니다. 위 쪽 코드에서는 제대로 되어있네요
@@ -0,0 +1,30 @@
+package christmas.domain;
+
+import java.text.DecimalFormat;
+
+public class Price {
+    private int price;
+
+    public Price(int price) {
+        this.price = price;
+    }
+
+    public void discount(int discountAmount) {
+        this.price -= discountAmount;
+        this.price = getItOrZero(this.price);
+    }
+
+    private String addComma(int price) {
+        DecimalFormat formatter = new DecimalFormat("###,###");
+        return formatter.format(price);
+    }
+
+    private int getItOrZero(int price) {
+        return Math.max(price, 0);
+    }
+
+    @Override
+    public String toString() {
+        return addComma(price);
+    }
+}

리뷰: 이렇게 가져오는 방법도있군요! 저는 `NumberFormat`를 사용해서 가져왔는데!
@@ -0,0 +1,31 @@
+package christmas.domain.event.discount;
+
+import christmas.constants.AmountConstants;
+import christmas.constants.DayConstants;
+import christmas.domain.day.Day;
+
+public class ChristmasDiscountEvent implements DiscountEvent {
+    private final Day presentDay;
+    private final Day startDay;
+
+    public ChristmasDiscountEvent(Day presentDay) {
+        this.presentDay = presentDay;
+        this.startDay = new Day(DayConstants.CHRISTMAS_START.getDay());
+    }
+
+    @Override
+    public boolean isDiscountable() {
+        return presentDay.isInBetween(DayConstants.CHRISTMAS_START.getDay(), DayConstants.CHRISTMAS_END.getDay());
+    }
+
+    @Override
+    public int getDiscountedAmount() {
+        int dayDifference = presentDay.getDifference(startDay);
+        return AmountConstants.CHRISTMAS_BASE.getAmount() + (AmountConstants.CHRISTMAS_UNIT.getAmount() * dayDifference);
+    }
+
+    @Override
+    public String toString() {
+        return "크리스마스 디데이 할인";
+    }
+}

리뷰: 하드코딩을 제거하면 좋을거같아요! 상수처리를 해도되고! 이벤트의 메시지를 관리하는 enum 클래스를 만드는것도 좋은방법일거같습니다!
@@ -0,0 +1,10 @@
+package christmas.domain.event.discount;
+
+public interface DiscountEvent {
+    public boolean isDiscountable();
+
+    public int getDiscountedAmount();
+
+    @Override
+    public String toString();
+}

리뷰: 메서드명을 좀더 명확하게 지으면 더 좋을거같아요!
@@ -0,0 +1,30 @@
+package christmas.domain;
+
+import java.text.DecimalFormat;
+
+public class Price {
+    private int price;
+
+    public Price(int price) {
+        this.price = price;
+    }
+
+    public void discount(int discountAmount) {
+        this.price -= discountAmount;
+        this.price = getItOrZero(this.price);
+    }
+
+    private String addComma(int price) {
+        DecimalFormat formatter = new DecimalFormat("###,###");
+        return formatter.format(price);
+    }
+
+    private int getItOrZero(int price) {
+        return Math.max(price, 0);
+    }
+
+    @Override
+    public String toString() {
+        return addComma(price);
+    }
+}

리뷰: 맞아요! 처음에는 3자리 수 단위로 쉼표로 끊는 메서드를 직접 만들까 생각하다가 자바 기본 API에 있을 것 같아서 찾으니 DecimalFormat이 있었습니다
@@ -0,0 +1,10 @@
+package christmas.domain.event.discount;
+
+public interface DiscountEvent {
+    public boolean isDiscountable();
+
+    public int getDiscountedAmount();
+
+    @Override
+    public String toString();
+}

리뷰: 그렇군요 다른 분들이 보시기에 메서드명이 명확하지 않을 수 있다는 것을 깨달았습니다. 
제가 프리코스를 하면서 느꼈던게 영어의 부족함이었습니다. 좀 더 납득이 갈 만한 메서드, 클래스 명을 짓고 싶은데 
도무지 그 자리에서 괜찮은 이름을 짓지 못했던 경험이 있습니다..
@@ -0,0 +1,31 @@
+package christmas.domain.event.discount;
+
+import christmas.constants.AmountConstants;
+import christmas.constants.DayConstants;
+import christmas.domain.day.Day;
+
+public class ChristmasDiscountEvent implements DiscountEvent {
+    private final Day presentDay;
+    private final Day startDay;
+
+    public ChristmasDiscountEvent(Day presentDay) {
+        this.presentDay = presentDay;
+        this.startDay = new Day(DayConstants.CHRISTMAS_START.getDay());
+    }
+
+    @Override
+    public boolean isDiscountable() {
+        return presentDay.isInBetween(DayConstants.CHRISTMAS_START.getDay(), DayConstants.CHRISTMAS_END.getDay());
+    }
+
+    @Override
+    public int getDiscountedAmount() {
+        int dayDifference = presentDay.getDifference(startDay);
+        return AmountConstants.CHRISTMAS_BASE.getAmount() + (AmountConstants.CHRISTMAS_UNIT.getAmount() * dayDifference);
+    }
+
+    @Override
+    public String toString() {
+        return "크리스마스 디데이 할인";
+    }
+}

리뷰: 앗 다른 상수들은 지나치지 않았는데 toString에 대해서는 상수로 처리하는 것을 깜빡한 것 같습니다.
지적 감사합니다.
@@ -0,0 +1,21 @@
+package christmas.constants;
+
+public enum AmountConstants {
+    CHRISTMAS_BASE(1_000),
+    CHRISTMAS_UNIT(100),
+    DISCOUNT_THRESHOLD(10_000),
+    HOLIDAY_UNIT(2_023),
+    STAR_DISCOUNT(1_000),
+    WEEKDAY_UNIT(2_023),
+    CHAMPAGNE_PRESENT_BASE(120_000);
+
+    private final int amount;
+
+    AmountConstants(int amount) {
+        this.amount = amount;
+    }
+
+    public int getAmount() {
+        return this.amount;
+    }
+}

리뷰: 아마 기능 요구사항 중

> 총주문 금액 10,000원 이상부터 이벤트가 적용됩니다.

을 구현할때 쓰이는 상수인거 같아요.

Discount뿐만 아니라 Event도 아우를 수 있게 DISCOUNT -> EVENT
Threshold를 잘 모르는 사람도 있을 수 있으니깐 THRESHOLD -> REQUIREMENT

로 해도 괜찮지 않을까 조심히 제안해봅니다!

저는 threshold라는 단어를 몰랐었는데
혹시 이 단어의 뜻의 늬앙스가 딱 맞아서 선택하신걸까요? 🤔
@@ -0,0 +1,49 @@
+package christmas.domain.event.discount;
+
+import christmas.constants.AmountConstants;
+import christmas.domain.day.Day;
+import christmas.domain.order.OrderSheet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public enum DiscountEventManager {
+    CHRISTMAS {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new ChristmasDiscountEvent(day);
+        }
+    },
+    HOLIDAY {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new HolidayDiscountEvent(day, orderSheet);
+        }
+    },
+    WEEKDAY {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new WeekDayDiscountEvent(day, orderSheet);
+        }
+    },
+    STAR {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new StarDiscountEvent(day);
+        }
+    };
+
+    abstract protected DiscountEvent create(Day day, OrderSheet orderSheet);
+
+    public static DiscountResult getDiscountResult(Day day, OrderSheet orderSheet) {
+        if (orderSheet.isMoreThanTotal(AmountConstants.DISCOUNT_THRESHOLD.getAmount())) {
+            List<DiscountEvent> discountEvents = Arrays.stream(values())
+                    .map(event -> event.create(day, orderSheet))
+                    .filter(DiscountEvent::isDiscountable)
+                    .toList();
+            return new DiscountResult(discountEvents);
+        }
+        return new DiscountResult(new ArrayList<>());
+    }
+}

리뷰: Enum에서 추상 메서드로 다형성을 구현하신 점이 굉장히 인상깊네요.

저렇게도 되는 줄은 몰랐어요 ㅎㅎ

https://techblog.woowahan.com/2527/

이전 코드리뷰에서 주신 링크인 여기에서 참고하신 건가요?
@@ -0,0 +1,30 @@
+package christmas.domain.event.present;
+
+import christmas.domain.order.Menu;
+import christmas.domain.order.OrderSheet;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum PresentEventManager {
+    CHAMPAGNE {
+        @Override
+        protected PresentEvent create(OrderSheet orderSheet) {
+            return new ChampagnePresentEvent(orderSheet);
+        }
+    };
+
+    abstract protected PresentEvent create(OrderSheet orderSheet);
+
+    public static PresentResult getPresentResult(OrderSheet orderSheet) {
+        Map<Menu, Integer> presents = new HashMap<>();
+        for (PresentEventManager value : values()) {
+            PresentEvent event = value.create(orderSheet);
+            if (event.isPresentable()) {
+                int presentCount = presents.getOrDefault(event.getPresent(), 1);
+                presents.put(event.getPresent(), presentCount);
+            }
+        }
+        return new PresentResult(presents);
+    }
+}

리뷰: Present와 Discount도 따로 구분하는 것도 인상깊네요.

이번 미션에서는 선물이 1개였지만,
여러 유형의 선물이 있을 시의 확장성을 고려하신거 같아요. 👍
@@ -0,0 +1,73 @@
+package christmas.domain.order;
+
+import christmas.constants.ErrorMessage;
+import christmas.domain.Price;
+import christmas.dto.MenuDTO;
+
+import java.util.*;
+
+public class OrderSheet {
+    private static final int TOTAL_COUNT_LIMIT = 20;
+
+    private final Map<Menu, Integer> orderSheet;
+    private int totalPrice;
+
+    public OrderSheet(Map<String, Integer> menus) {
+        orderSheet = new HashMap<>();
+        validateExceedMenuCount(menus);
+        countMenu(menus);
+        calculateTotalPrice();
+        validateOnlyDrink();
+    }
+
+    public int getMenuCountByMenuType(MenuType menuType) {
+        int menuCount = orderSheet.keySet().stream()
+                .filter(menu -> menu.compareType(menuType))
+                .map(menu -> orderSheet.get(menu))
+                .reduce(0, Integer::sum);
+        return menuCount;
+    }
+
+    public int calculateTotalPrice() {
+        this.totalPrice = orderSheet.keySet().stream()
+                .map(menu -> menu.getPrice() * orderSheet.get(menu))
+                .reduce(0, Integer::sum);
+        return totalPrice;
+    }
+
+    private void countMenu(Map<String, Integer> menus) {
+        for (String menuName : menus.keySet()) {
+            Menu menu = Menu.getMenuByName(menuName);
+            orderSheet.put(menu, menus.get(menuName));
+        }
+    }
+
+    public Price getTotalPrice() {
+        return new Price(totalPrice);
+    }
+
+    public List<MenuDTO> getOrderSheet() {
+        return orderSheet.keySet().stream()
+                .map(menu -> new MenuDTO(menu.getName(), orderSheet.get(menu)))
+                .toList();
+    }
+
+    public boolean isMoreThanTotal(int amount) {
+        return totalPrice >= amount;
+    }
+
+    private void validateExceedMenuCount(Map<String, Integer> menus) {
+        int totalMenuCount = menus.values().stream()
+                .reduce(0, Integer::sum);
+        if (totalMenuCount <= TOTAL_COUNT_LIMIT) return;
+        throw new IllegalArgumentException(ErrorMessage.EXCEED_MENU_COUNT.getErrorMessage());
+    }
+
+    private void validateOnlyDrink() {
+        int drinkCount = (int) orderSheet.keySet().stream()
+                .filter(menu -> menu.compareType(MenuType.DRINK))
+                .count();
+        if (drinkCount == orderSheet.size())
+            throw new IllegalArgumentException(ErrorMessage.ONLY_DRINK.getErrorMessage());
+    }
+}

리뷰: countMenu 네이밍은 Menu의 개수를 반환하는 함수라는 느낌이 들어요.

혹시 제가 모르는 count의 다른 뜻이 있는 건가요? 🤔
@@ -0,0 +1,73 @@
+package christmas.domain.order;
+
+import christmas.constants.ErrorMessage;
+import christmas.domain.Price;
+import christmas.dto.MenuDTO;
+
+import java.util.*;
+
+public class OrderSheet {
+    private static final int TOTAL_COUNT_LIMIT = 20;
+
+    private final Map<Menu, Integer> orderSheet;
+    private int totalPrice;
+
+    public OrderSheet(Map<String, Integer> menus) {
+        orderSheet = new HashMap<>();
+        validateExceedMenuCount(menus);
+        countMenu(menus);
+        calculateTotalPrice();
+        validateOnlyDrink();
+    }
+
+    public int getMenuCountByMenuType(MenuType menuType) {
+        int menuCount = orderSheet.keySet().stream()
+                .filter(menu -> menu.compareType(menuType))
+                .map(menu -> orderSheet.get(menu))
+                .reduce(0, Integer::sum);
+        return menuCount;
+    }
+
+    public int calculateTotalPrice() {
+        this.totalPrice = orderSheet.keySet().stream()
+                .map(menu -> menu.getPrice() * orderSheet.get(menu))
+                .reduce(0, Integer::sum);
+        return totalPrice;
+    }
+
+    private void countMenu(Map<String, Integer> menus) {
+        for (String menuName : menus.keySet()) {
+            Menu menu = Menu.getMenuByName(menuName);
+            orderSheet.put(menu, menus.get(menuName));
+        }
+    }
+
+    public Price getTotalPrice() {
+        return new Price(totalPrice);
+    }
+
+    public List<MenuDTO> getOrderSheet() {
+        return orderSheet.keySet().stream()
+                .map(menu -> new MenuDTO(menu.getName(), orderSheet.get(menu)))
+                .toList();
+    }
+
+    public boolean isMoreThanTotal(int amount) {
+        return totalPrice >= amount;
+    }
+
+    private void validateExceedMenuCount(Map<String, Integer> menus) {
+        int totalMenuCount = menus.values().stream()
+                .reduce(0, Integer::sum);
+        if (totalMenuCount <= TOTAL_COUNT_LIMIT) return;
+        throw new IllegalArgumentException(ErrorMessage.EXCEED_MENU_COUNT.getErrorMessage());
+    }
+
+    private void validateOnlyDrink() {
+        int drinkCount = (int) orderSheet.keySet().stream()
+                .filter(menu -> menu.compareType(MenuType.DRINK))
+                .count();
+        if (drinkCount == orderSheet.size())
+            throw new IllegalArgumentException(ErrorMessage.ONLY_DRINK.getErrorMessage());
+    }
+}

리뷰: `Stream`의 `allMatch()`를 사용해도 스트림 내의 모든 요소들이 `MenuType.DRINK`인지 검증할 수 있더라구여 :)

이걸 사용하면 코드 길이를 줄일 수 있고 좀 더 의미가 명확해지지 않나 싶습니다!
@@ -0,0 +1,21 @@
+package christmas.constants;
+
+public enum AmountConstants {
+    CHRISTMAS_BASE(1_000),
+    CHRISTMAS_UNIT(100),
+    DISCOUNT_THRESHOLD(10_000),
+    HOLIDAY_UNIT(2_023),
+    STAR_DISCOUNT(1_000),
+    WEEKDAY_UNIT(2_023),
+    CHAMPAGNE_PRESENT_BASE(120_000);
+
+    private final int amount;
+
+    AmountConstants(int amount) {
+        this.amount = amount;
+    }
+
+    public int getAmount() {
+        return this.amount;
+    }
+}

리뷰: 우선 제 코드 리뷰가 도움이 되었다는 사실에 감격스럽다는 말을 전하고 싶어요! 감사하다는 말을 들을 때마다 힘이 나는 것 같습니다. 
게다가 이렇게 코드 리뷰를 받으니 두배로 감격스러워요!

제안에 동의합니다. 확실히 모든 이벤트는 만원을 넘어야하니 DISCOUNT 보다 EVENT 가 문맥에 맞을 것 같고,
"이벤트를 받기 위해 이만큼 필요하다"라는 문맥을 잘 전달할 수 있도록 REQUIREMENT가 더욱 잘 맞는 것 같아요. (이건 제가 영어공부 좀 해야할 것 같습니다)
@@ -0,0 +1,49 @@
+package christmas.domain.event.discount;
+
+import christmas.constants.AmountConstants;
+import christmas.domain.day.Day;
+import christmas.domain.order.OrderSheet;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public enum DiscountEventManager {
+    CHRISTMAS {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new ChristmasDiscountEvent(day);
+        }
+    },
+    HOLIDAY {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new HolidayDiscountEvent(day, orderSheet);
+        }
+    },
+    WEEKDAY {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new WeekDayDiscountEvent(day, orderSheet);
+        }
+    },
+    STAR {
+        @Override
+        protected DiscountEvent create(Day day, OrderSheet orderSheet) {
+            return new StarDiscountEvent(day);
+        }
+    };
+
+    abstract protected DiscountEvent create(Day day, OrderSheet orderSheet);
+
+    public static DiscountResult getDiscountResult(Day day, OrderSheet orderSheet) {
+        if (orderSheet.isMoreThanTotal(AmountConstants.DISCOUNT_THRESHOLD.getAmount())) {
+            List<DiscountEvent> discountEvents = Arrays.stream(values())
+                    .map(event -> event.create(day, orderSheet))
+                    .filter(DiscountEvent::isDiscountable)
+                    .toList();
+            return new DiscountResult(discountEvents);
+        }
+        return new DiscountResult(new ArrayList<>());
+    }
+}

리뷰: 네 맞습니다. 
이 포스트를 보기 전 "만약 이벤트가 늘어난다면 어떻게 하지?"라는 생각이 들었습니다. 하지만 이벤트 각자마다 이벤트 적용가능한지 계산하기 위해 다른 파라미터의 종류를 가지고 있었습니다. 
이후에 이 포스트에서 Enum의 추상 메서드로 상수 별 메서드를 다르게 하는 모습을 보고 이벤트 객체를 생성하는 메서드를 만들면 유연하게 이벤트를 추가할 수 있겠다 싶었습니다.
이는 Enum 메서드가 객체 생성을 담당하는 패턴, Enum Factory Method Pattern 입니다. 
기존 팩토리 패턴과 다르게 싱글톤으로 팩토리 이용하기 때문에 메모리 낭비로 이루어지지 않고 새로운 이벤트 객체가 생길 때마다 이벤트 팩토리를 만들어야했던 기존 패턴과 다르게 클래스 안에서 쉽게 정의가 가능하다는 장점이 있습니다.
이에 대한 내용은 https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-Enum-Factory-Method-%EB%B3%80%ED%98%95-%ED%8C%A8%ED%84%B4 을 보고 알게 되었습니다.