ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,61 @@
+package christmas.domain.model;
+
+import christmas.domain.type.Badge;
+import christmas.domain.type.Benefit;
+
+import java.util.Map;
+
+public class EventResult {
+    private final OrderInfo orderInfo;
+    private final Map<Benefit, Integer> benefitHistory;
+    private final int totalBenefitsPrice;
+    private final int finalPrice;
+    private final Badge badge;
+
+    public EventResult(OrderInfo orderInfo, Map<Benefit, Integer> benefitHistory, int totalBenefitsPrice, Badge badge) {
+        this.orderInfo = orderInfo;
+        this.benefitHistory = benefitHistory;
+        this.totalBenefitsPrice = totalBenefitsPrice;
+        this.finalPrice = calculateFinalPrice();
+        this.badge = badge;
+    }
+
+    // getter
+    public OrderInfo getOrder() {
+        return orderInfo;
+    }
+
+    public Map<Benefit, Integer> getBenefitHistory() {
+        return benefitHistory;
+    }
+
+    public int getTotalBenefitsPrice() {
+        return totalBenefitsPrice;
+    }
+
+    public int getFinalPrice() {
+        return finalPrice;
+    }
+
+    public Badge getBadge() {
+        return badge;
+    }
+
+    public boolean hasGiveawayBenefits() {
+        if (benefitHistory.containsKey(Benefit.GIVEAWAY)) {
+            return true;
+        }
+        return false;
+    }
+
+    //private 헬퍼
+    private int calculateFinalPrice() {
+        int finalPrice = orderInfo.getTotalOrderPrice() - totalBenefitsPrice;
+
+        if (benefitHistory.containsKey(Benefit.GIVEAWAY)) {
+           finalPrice += benefitHistory.get(Benefit.GIVEAWAY);
+        }
+
+        return finalPrice;
+    }
+}

리뷰: EventResult는 dto로 사용하신걸까요?
@@ -0,0 +1,41 @@
+package christmas.domain.model;
+
+import christmas.domain.type.Menu;
+
+import java.util.Map;
+
+public class OrderInfo {
+    private final int date;
+    private final Map<Menu, Integer> order;
+    private final int totalOrderPrice;
+
+    public OrderInfo(int date, Map<Menu, Integer> order) {
+        this.date = date;
+        this.order = order;
+        this.totalOrderPrice = calculateTotalOrderPrice();
+    }
+
+    public int getDate() {
+        return date;
+    }
+    public Map<Menu, Integer> getOrder() {
+        return order;
+    }
+
+    public int getTotalOrderPrice() {
+        return totalOrderPrice;
+    }
+
+    private int calculateTotalOrderPrice() {
+        int totalOrderPrice = 0;
+
+        for (Map.Entry<Menu, Integer> entry : order.entrySet()) {
+            Menu menu = entry.getKey();
+            int quantity = entry.getValue();
+
+            totalOrderPrice += menu.getPrice() * quantity;
+        }
+
+        return totalOrderPrice;
+    }
+}

리뷰: 자신이 가진 값으로 한번 정해지고 변하지 않는 값이어서 이렇게 구현했습니다!
orderInfo의 값은 다른 곳에서 활용됩니다
@@ -0,0 +1,58 @@
+package christmas.domain.type;
+
+public enum Menu {
+    //에피타이저
+    MUSHROOM_SOUP("양송이수프", 6_000, Category.APPETIZER),
+    TAPAS("타파스", 5_500, Category.APPETIZER),
+    CAESAR_SALAD("시저샐러드", 8_000, Category.APPETIZER),
+
+    //메인
+    T_BONE_STEAK("티본스테이크", 55_000, Category.MAIN),
+    BBQ_RIBS("바비큐립", 54_000, Category.MAIN),
+    SEAFOOD_PASTA("해산물파스타", 35_000, Category.MAIN),
+    CHRISTMAS_PASTA("크리스마스파스타", 25_000, Category.MAIN),
+
+    //디저트
+    CHOCOLATE_CAKE("초코케이크", 15_000, Category.DESSERT),
+    ICE_CREAM("아이스크림", 5_000, Category.DESSERT),
+
+    //음료
+    ZERO_COKE("제로콜라", 3_000, Category.BEVERAGE),
+    RED_WINE("레드와인", 60_000, Category.BEVERAGE),
+    CHAMPAGNE("샴페인", 25_000, Category.BEVERAGE);
+
+    private final String name;
+    private final int price;
+    private final Category category;
+
+    Menu(String name, int price, Category category) {
+        this.name = name;
+        this.price = price;
+        this.category = category;
+    }
+
+    public static Menu findByName(String menuName) {
+        for (Menu menu : Menu.values()) {
+            if (menu.getName().equals(menuName)) {
+                return menu;
+            }
+        }
+        return null;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getPrice() {
+        return price;
+    }
+
+    public Category getCategory() {
+        return category;
+    }
+
+    public enum Category {
+        APPETIZER, MAIN, DESSERT, BEVERAGE
+    }
+}

리뷰: 다슬님 코드에서 한수 배웠습니다!
@@ -0,0 +1,58 @@
+package christmas.domain.type;
+
+public enum Menu {
+    //에피타이저
+    MUSHROOM_SOUP("양송이수프", 6_000, Category.APPETIZER),
+    TAPAS("타파스", 5_500, Category.APPETIZER),
+    CAESAR_SALAD("시저샐러드", 8_000, Category.APPETIZER),
+
+    //메인
+    T_BONE_STEAK("티본스테이크", 55_000, Category.MAIN),
+    BBQ_RIBS("바비큐립", 54_000, Category.MAIN),
+    SEAFOOD_PASTA("해산물파스타", 35_000, Category.MAIN),
+    CHRISTMAS_PASTA("크리스마스파스타", 25_000, Category.MAIN),
+
+    //디저트
+    CHOCOLATE_CAKE("초코케이크", 15_000, Category.DESSERT),
+    ICE_CREAM("아이스크림", 5_000, Category.DESSERT),
+
+    //음료
+    ZERO_COKE("제로콜라", 3_000, Category.BEVERAGE),
+    RED_WINE("레드와인", 60_000, Category.BEVERAGE),
+    CHAMPAGNE("샴페인", 25_000, Category.BEVERAGE);
+
+    private final String name;
+    private final int price;
+    private final Category category;
+
+    Menu(String name, int price, Category category) {
+        this.name = name;
+        this.price = price;
+        this.category = category;
+    }
+
+    public static Menu findByName(String menuName) {
+        for (Menu menu : Menu.values()) {
+            if (menu.getName().equals(menuName)) {
+                return menu;
+            }
+        }
+        return null;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getPrice() {
+        return price;
+    }
+
+    public Category getCategory() {
+        return category;
+    }
+
+    public enum Category {
+        APPETIZER, MAIN, DESSERT, BEVERAGE
+    }
+}

리뷰: 책임을 분리하려고 그렇게 작성했습니다.
바로 메뉴에서 예외를 던지면 추적하기 쉬울수 있겠네요
@@ -0,0 +1,41 @@
+package christmas.domain.model;
+
+import christmas.domain.type.Menu;
+
+import java.util.Map;
+
+public class OrderInfo {
+    private final int date;
+    private final Map<Menu, Integer> order;
+    private final int totalOrderPrice;
+
+    public OrderInfo(int date, Map<Menu, Integer> order) {
+        this.date = date;
+        this.order = order;
+        this.totalOrderPrice = calculateTotalOrderPrice();
+    }
+
+    public int getDate() {
+        return date;
+    }
+    public Map<Menu, Integer> getOrder() {
+        return order;
+    }
+
+    public int getTotalOrderPrice() {
+        return totalOrderPrice;
+    }
+
+    private int calculateTotalOrderPrice() {
+        int totalOrderPrice = 0;
+
+        for (Map.Entry<Menu, Integer> entry : order.entrySet()) {
+            Menu menu = entry.getKey();
+            int quantity = entry.getValue();
+
+            totalOrderPrice += menu.getPrice() * quantity;
+        }
+
+        return totalOrderPrice;
+    }
+}

리뷰: date에 대한 validation을 InputView에서 진행하셨군요!
저도 이 부분에 대해서 어떤 것이 더 효율적일까 고민을 많이 해봤는데 @T3rryAhn 님의 생각은 어떤 지 여쭙고 싶습니다.

저도 처음에는 입력값에 대한 validation을 InputView에서 처리하는 것이 좋을지 domain에서 처리하는 것이 좋을 지 고민을 많이 했었는데요. 프로그램이 복잡해질 수록 InputView가 검증해야할 validation의 종류가 많아짐으로 저는 validation을 domain으로 책임을 넘기는 것이 더 좋다고 판단했습니다.

예를 들어 저는 InputView에서 validation은 최소한의 입력 오류(Ex. `NumberFormatException`, 빈 입력값, 글자수 제한 등)만 검증하고, 입력이 domain 관련 값으로 유효한 지 판단하는 건, 모델 객체 스스로가 자신의 값을 검증하도록 구조를 세웠습니다.

@T3rryAhn 님의 생각은 어떠신가요?

참고 : https://tecoble.techcourse.co.kr/post/2020-05-29-wrap-primitive-type/
@@ -0,0 +1,41 @@
+package christmas.domain.model;
+
+import christmas.domain.type.Menu;
+
+import java.util.Map;
+
+public class OrderInfo {
+    private final int date;
+    private final Map<Menu, Integer> order;
+    private final int totalOrderPrice;
+
+    public OrderInfo(int date, Map<Menu, Integer> order) {
+        this.date = date;
+        this.order = order;
+        this.totalOrderPrice = calculateTotalOrderPrice();
+    }
+
+    public int getDate() {
+        return date;
+    }
+    public Map<Menu, Integer> getOrder() {
+        return order;
+    }
+
+    public int getTotalOrderPrice() {
+        return totalOrderPrice;
+    }
+
+    private int calculateTotalOrderPrice() {
+        int totalOrderPrice = 0;
+
+        for (Map.Entry<Menu, Integer> entry : order.entrySet()) {
+            Menu menu = entry.getKey();
+            int quantity = entry.getValue();
+
+            totalOrderPrice += menu.getPrice() * quantity;
+        }
+
+        return totalOrderPrice;
+    }
+}

리뷰: Map<Menu, Integer>의 경우 컬렉션에 해당합니다.
이 경우 일급 컬렉션을 사용해서 관리하는 건 어떨까요?

참고 : https://tecoble.techcourse.co.kr/post/2020-05-08-First-Class-Collection/
@@ -0,0 +1,41 @@
+package christmas.domain.model;
+
+import christmas.domain.type.Menu;
+
+import java.util.Map;
+
+public class OrderInfo {
+    private final int date;
+    private final Map<Menu, Integer> order;
+    private final int totalOrderPrice;
+
+    public OrderInfo(int date, Map<Menu, Integer> order) {
+        this.date = date;
+        this.order = order;
+        this.totalOrderPrice = calculateTotalOrderPrice();
+    }
+
+    public int getDate() {
+        return date;
+    }
+    public Map<Menu, Integer> getOrder() {
+        return order;
+    }
+
+    public int getTotalOrderPrice() {
+        return totalOrderPrice;
+    }
+
+    private int calculateTotalOrderPrice() {
+        int totalOrderPrice = 0;
+
+        for (Map.Entry<Menu, Integer> entry : order.entrySet()) {
+            Menu menu = entry.getKey();
+            int quantity = entry.getValue();
+
+            totalOrderPrice += menu.getPrice() * quantity;
+        }
+
+        return totalOrderPrice;
+    }
+}

리뷰: 3주차 공통 피드백에서 '**객체는 객체답게 **'라는 것이 있었습니다.
이 경우 `private final Map<Menu, Integer> order;`으로 선언한 order을 반환하는데요.

Map<Menu, Integer>은 컬렉션 중에 하나입니다.
따라서 final 키워드를 사용한다고 해도 값의 변경이 발생할 수 있습니다 ㅠㅡㅠ.

따라서 컬렉션 변수는 최대한 getter 사용을 지양하고 객체에 메시지를 던지는 방식으로 처리하면 좋은데요.
위의 comment와 연관하여 '일급컬렉션' 개념이 많이 도움 되실 것 같습니다!

참고 : https://tecoble.techcourse.co.kr/post/2020-05-08-First-Class-Collection/
@@ -0,0 +1,82 @@
+package christmas.controller;
+
+import static christmas.domain.event.EventConstants.*;
+
+import christmas.domain.restaurant.Orders;
+import christmas.domain.restaurant.VisitDate;
+import christmas.service.RestaurantCalculator;
+import christmas.view.inputview.InputValueType;
+import christmas.view.inputview.InputView;
+import christmas.view.outputview.OutputView;
+
+public class WootecoRestaurantController {
+    private final RestaurantCalculator restaurantCalculator;
+    private final EventPlanerController eventPlanerController;
+
+    public WootecoRestaurantController(RestaurantCalculator restaurantCalculator,
+                                       EventPlanerController eventPlanerController) {
+        this.restaurantCalculator = restaurantCalculator;
+        this.eventPlanerController = eventPlanerController;
+    }
+
+    public void takeReservation() {
+        VisitDate visitDate = getVisitDate();
+        Orders orders = getOrders();
+        int orderTotalAmount = getOrderTotalAmount(orders);
+
+        showEventPreviewMessage(visitDate);
+        showOrderDetails(orders, orderTotalAmount);
+        executeEvent(visitDate, orders, orderTotalAmount);
+    }
+
+    private VisitDate getVisitDate() {
+        OutputView.printHelloMessage();
+        VisitDate visitDate = inputVisitDate();
+        return visitDate;
+    }
+
+    private Orders getOrders() {
+        OutputView.printMenu();
+        Orders orders = inputOrders();
+        return orders;
+    }
+
+    private int getOrderTotalAmount(Orders orders) {
+        return restaurantCalculator.getOrderTotalAmount(orders);
+    }
+
+    private static void showEventPreviewMessage(VisitDate visitDate) {
+        OutputView.printEventPreviewMessage(visitDate);
+    }
+
+    private static void showOrderDetails(Orders orders, int orderTotalAmount) {
+        OutputView.printOrder(orders, orderTotalAmount);
+    }
+
+    private void executeEvent(VisitDate visitDate, Orders orders, int orderTotalAmount) {
+        if (canApplyEvent(orderTotalAmount)) {
+            eventPlanerController.executeEventPlaner(visitDate, orders, orderTotalAmount);
+        }
+    }
+
+    private boolean canApplyEvent(int orderTotalAmount) {
+        if (isOrderTotalAmountValidForEvent(orderTotalAmount)) {
+            return true;
+        }
+
+        eventPlanerController.notApplyEvent(orderTotalAmount);
+        return false;
+    }
+
+    private static boolean isOrderTotalAmountValidForEvent(int orderTotalAmount) {
+        return orderTotalAmount >= EVENT_MIN_PAY_AMOUNT.getValue();
+    }
+
+    private Orders inputOrders() {
+        return (Orders) InputView.inputValue(InputValueType.ORDERS);
+    }
+
+    private VisitDate inputVisitDate() {
+        return (VisitDate) InputView.inputValue(InputValueType.VISIT_DATE);
+    }
+}

리뷰: 개인적인 생각으로, 컨트롤러가 다른 컨트롤러를 인스턴스 변수로 가지고 호출하는 것이 맞는지 잘 모르겠습니다.

만약 공통된 부분이 있어서라면, 서비스를 따로 두거나 컨트롤러를 하나로 합치는걸 추천드립니다!
@@ -0,0 +1,78 @@
+package christmas.domain.restaurant;
+
+import christmas.domain.food.Dessert;
+import christmas.domain.food.Food;
+import christmas.domain.food.MainFood;
+import christmas.util.parser.Parser;
+import christmas.util.validator.OrderValidator;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public class Orders {
+    private final Map<Food, Integer> orders;
+
+    private Orders(String orders) {
+        validate(orders);
+        this.orders = registerOrders(orders);
+    }
+
+    public static Orders create(String orders) {
+        return new Orders(orders);
+    }
+
+    public int getMainMenuCount() {
+        int mainMenuCount = 0;
+
+        for (Entry<Food, Integer> entry : orders.entrySet()) {
+            Food menu = entry.getKey();
+            int menuCount = entry.getValue();
+
+            if (menu instanceof MainFood) {
+                mainMenuCount += menuCount;
+            }
+        }
+
+        return mainMenuCount;
+    }
+
+    public int getDessertMenuCount() {
+        int dessertMenuCount = 0;
+
+        for (Entry<Food, Integer> entry : orders.entrySet()) {
+            Food menu = entry.getKey();
+            int menuCount = entry.getValue();
+
+            if (menu instanceof Dessert) {
+                dessertMenuCount += menuCount;
+            }
+        }
+
+        return dessertMenuCount;
+    }
+
+    private void validate(String orders) {
+        OrderValidator.validateOrders(orders);
+    }
+
+    private Map<Food, Integer> registerOrders(String orders) {
+        List<String> menus = Parser.parseMenus(orders);
+        List<Integer> counts = Parser.parseMenuCounts(orders);
+        Map<Food, Integer> order = new HashMap<>();
+
+        for (int idx = 0; idx < menus.size(); idx++) {
+            String menuName = menus.get(idx);
+            Food food = Menu.getFoodByName(menuName);
+            int count = counts.get(idx);
+
+            order.put(food, count);
+        }
+        return order;
+    }
+
+    public Map<Food, Integer> getOrders() {
+        return Collections.unmodifiableMap(orders);
+    }
+}

리뷰: Map 자료구조는 쓰다보면 은근 손이 많이 가게되는 자료구조라는 생각이 들더라구요.

물론 자료구조마다 장점과 단점이 있지만

개인적으로 여기서는 Map보다는 메뉴와 개수를 가진 별도의 Order 객체를 두는 것이 좋아보입니다!
@@ -0,0 +1,82 @@
+package christmas.controller;
+
+import static christmas.domain.event.EventConstants.*;
+
+import christmas.domain.restaurant.Orders;
+import christmas.domain.restaurant.VisitDate;
+import christmas.service.RestaurantCalculator;
+import christmas.view.inputview.InputValueType;
+import christmas.view.inputview.InputView;
+import christmas.view.outputview.OutputView;
+
+public class WootecoRestaurantController {
+    private final RestaurantCalculator restaurantCalculator;
+    private final EventPlanerController eventPlanerController;
+
+    public WootecoRestaurantController(RestaurantCalculator restaurantCalculator,
+                                       EventPlanerController eventPlanerController) {
+        this.restaurantCalculator = restaurantCalculator;
+        this.eventPlanerController = eventPlanerController;
+    }
+
+    public void takeReservation() {
+        VisitDate visitDate = getVisitDate();
+        Orders orders = getOrders();
+        int orderTotalAmount = getOrderTotalAmount(orders);
+
+        showEventPreviewMessage(visitDate);
+        showOrderDetails(orders, orderTotalAmount);
+        executeEvent(visitDate, orders, orderTotalAmount);
+    }
+
+    private VisitDate getVisitDate() {
+        OutputView.printHelloMessage();
+        VisitDate visitDate = inputVisitDate();
+        return visitDate;
+    }
+
+    private Orders getOrders() {
+        OutputView.printMenu();
+        Orders orders = inputOrders();
+        return orders;
+    }
+
+    private int getOrderTotalAmount(Orders orders) {
+        return restaurantCalculator.getOrderTotalAmount(orders);
+    }
+
+    private static void showEventPreviewMessage(VisitDate visitDate) {
+        OutputView.printEventPreviewMessage(visitDate);
+    }
+
+    private static void showOrderDetails(Orders orders, int orderTotalAmount) {
+        OutputView.printOrder(orders, orderTotalAmount);
+    }
+
+    private void executeEvent(VisitDate visitDate, Orders orders, int orderTotalAmount) {
+        if (canApplyEvent(orderTotalAmount)) {
+            eventPlanerController.executeEventPlaner(visitDate, orders, orderTotalAmount);
+        }
+    }
+
+    private boolean canApplyEvent(int orderTotalAmount) {
+        if (isOrderTotalAmountValidForEvent(orderTotalAmount)) {
+            return true;
+        }
+
+        eventPlanerController.notApplyEvent(orderTotalAmount);
+        return false;
+    }
+
+    private static boolean isOrderTotalAmountValidForEvent(int orderTotalAmount) {
+        return orderTotalAmount >= EVENT_MIN_PAY_AMOUNT.getValue();
+    }
+
+    private Orders inputOrders() {
+        return (Orders) InputView.inputValue(InputValueType.ORDERS);
+    }
+
+    private VisitDate inputVisitDate() {
+        return (VisitDate) InputView.inputValue(InputValueType.VISIT_DATE);
+    }
+}

리뷰: 해당 부분은 이벤트 도메인 관련 클래스에 위치하는 것이 좋아보입니다. 
이벤트를 적용할 수 있는지 없는지에 대해서는 비즈니스 로직에 해당된다고 생각해요!
@@ -0,0 +1,82 @@
+package christmas.controller;
+
+import static christmas.domain.event.EventConstants.*;
+
+import christmas.domain.restaurant.Orders;
+import christmas.domain.restaurant.VisitDate;
+import christmas.service.RestaurantCalculator;
+import christmas.view.inputview.InputValueType;
+import christmas.view.inputview.InputView;
+import christmas.view.outputview.OutputView;
+
+public class WootecoRestaurantController {
+    private final RestaurantCalculator restaurantCalculator;
+    private final EventPlanerController eventPlanerController;
+
+    public WootecoRestaurantController(RestaurantCalculator restaurantCalculator,
+                                       EventPlanerController eventPlanerController) {
+        this.restaurantCalculator = restaurantCalculator;
+        this.eventPlanerController = eventPlanerController;
+    }
+
+    public void takeReservation() {
+        VisitDate visitDate = getVisitDate();
+        Orders orders = getOrders();
+        int orderTotalAmount = getOrderTotalAmount(orders);
+
+        showEventPreviewMessage(visitDate);
+        showOrderDetails(orders, orderTotalAmount);
+        executeEvent(visitDate, orders, orderTotalAmount);
+    }
+
+    private VisitDate getVisitDate() {
+        OutputView.printHelloMessage();
+        VisitDate visitDate = inputVisitDate();
+        return visitDate;
+    }
+
+    private Orders getOrders() {
+        OutputView.printMenu();
+        Orders orders = inputOrders();
+        return orders;
+    }
+
+    private int getOrderTotalAmount(Orders orders) {
+        return restaurantCalculator.getOrderTotalAmount(orders);
+    }
+
+    private static void showEventPreviewMessage(VisitDate visitDate) {
+        OutputView.printEventPreviewMessage(visitDate);
+    }
+
+    private static void showOrderDetails(Orders orders, int orderTotalAmount) {
+        OutputView.printOrder(orders, orderTotalAmount);
+    }
+
+    private void executeEvent(VisitDate visitDate, Orders orders, int orderTotalAmount) {
+        if (canApplyEvent(orderTotalAmount)) {
+            eventPlanerController.executeEventPlaner(visitDate, orders, orderTotalAmount);
+        }
+    }
+
+    private boolean canApplyEvent(int orderTotalAmount) {
+        if (isOrderTotalAmountValidForEvent(orderTotalAmount)) {
+            return true;
+        }
+
+        eventPlanerController.notApplyEvent(orderTotalAmount);
+        return false;
+    }
+
+    private static boolean isOrderTotalAmountValidForEvent(int orderTotalAmount) {
+        return orderTotalAmount >= EVENT_MIN_PAY_AMOUNT.getValue();
+    }
+
+    private Orders inputOrders() {
+        return (Orders) InputView.inputValue(InputValueType.ORDERS);
+    }
+
+    private VisitDate inputVisitDate() {
+        return (VisitDate) InputView.inputValue(InputValueType.VISIT_DATE);
+    }
+}

리뷰: 마찬가지의 이유로, view에서는 도메인 모델 자체가 아닌 도메인 모델의 데이터만 전달하는 것이 좋다고 생각합니다
@@ -0,0 +1,82 @@
+package christmas.controller;
+
+import static christmas.domain.event.EventConstants.*;
+
+import christmas.domain.restaurant.Orders;
+import christmas.domain.restaurant.VisitDate;
+import christmas.service.RestaurantCalculator;
+import christmas.view.inputview.InputValueType;
+import christmas.view.inputview.InputView;
+import christmas.view.outputview.OutputView;
+
+public class WootecoRestaurantController {
+    private final RestaurantCalculator restaurantCalculator;
+    private final EventPlanerController eventPlanerController;
+
+    public WootecoRestaurantController(RestaurantCalculator restaurantCalculator,
+                                       EventPlanerController eventPlanerController) {
+        this.restaurantCalculator = restaurantCalculator;
+        this.eventPlanerController = eventPlanerController;
+    }
+
+    public void takeReservation() {
+        VisitDate visitDate = getVisitDate();
+        Orders orders = getOrders();
+        int orderTotalAmount = getOrderTotalAmount(orders);
+
+        showEventPreviewMessage(visitDate);
+        showOrderDetails(orders, orderTotalAmount);
+        executeEvent(visitDate, orders, orderTotalAmount);
+    }
+
+    private VisitDate getVisitDate() {
+        OutputView.printHelloMessage();
+        VisitDate visitDate = inputVisitDate();
+        return visitDate;
+    }
+
+    private Orders getOrders() {
+        OutputView.printMenu();
+        Orders orders = inputOrders();
+        return orders;
+    }
+
+    private int getOrderTotalAmount(Orders orders) {
+        return restaurantCalculator.getOrderTotalAmount(orders);
+    }
+
+    private static void showEventPreviewMessage(VisitDate visitDate) {
+        OutputView.printEventPreviewMessage(visitDate);
+    }
+
+    private static void showOrderDetails(Orders orders, int orderTotalAmount) {
+        OutputView.printOrder(orders, orderTotalAmount);
+    }
+
+    private void executeEvent(VisitDate visitDate, Orders orders, int orderTotalAmount) {
+        if (canApplyEvent(orderTotalAmount)) {
+            eventPlanerController.executeEventPlaner(visitDate, orders, orderTotalAmount);
+        }
+    }
+
+    private boolean canApplyEvent(int orderTotalAmount) {
+        if (isOrderTotalAmountValidForEvent(orderTotalAmount)) {
+            return true;
+        }
+
+        eventPlanerController.notApplyEvent(orderTotalAmount);
+        return false;
+    }
+
+    private static boolean isOrderTotalAmountValidForEvent(int orderTotalAmount) {
+        return orderTotalAmount >= EVENT_MIN_PAY_AMOUNT.getValue();
+    }
+
+    private Orders inputOrders() {
+        return (Orders) InputView.inputValue(InputValueType.ORDERS);
+    }
+
+    private VisitDate inputVisitDate() {
+        return (VisitDate) InputView.inputValue(InputValueType.VISIT_DATE);
+    }
+}

리뷰: 이 부분은 구조 개선이 필요하겠네요. 말씀해주신대로 컨트롤러 내부에 컨트롤러를 둘 필요는 없었다고 생각합니다. EventPlanerController는 Service에 두는 게 맞았겠네요.

덕분에 어렴풋하게 알았던 서비스와 컨트롤러의 역할에 대해 다시 한 번 생각해볼 수 있는 기회가 된 것 같습니다. 좋은 피드백 감사합니다!