ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,47 @@
+package christmas.controller;
+
+import java.util.Map;
+
+import christmas.view.*;
+import christmas.model.*;
+
+public class MainController {
+    private OrderMenu orderMenu;
+
+    public MainController() {
+        orderMenu = new OrderMenu();
+    }
+
+    public void run() {
+        orderMenu.setOrderDate(InputView.readDate());
+        setReadOrder();
+
+        OutputView.printPreview(orderMenu.getOrderDate());
+        OutputView.printOrder(orderMenu.getUserOrder());
+        int totalPrice = orderMenu.getTotalPrice();
+        OutputView.printTotalPrice(totalPrice);
+        OutputView.printPresent(totalPrice);
+        benefitControl(totalPrice);
+    }
+
+    private void benefitControl(int totalPrice) {
+        Benefit benefit = new Benefit(orderMenu.getOrderDate(), orderMenu.getCategoryCount(), totalPrice);
+        OutputView.printBenefits(benefit.getBenefits());
+
+        int totalBenefitPrice = benefit.getTotalBenefitPrice();
+        OutputView.printTotalBenefitPrice(totalBenefitPrice);
+        OutputView.printTotalPayment(totalPrice - totalBenefitPrice + benefit.getPresentPrice());
+        OutputView.printEventBadge(totalBenefitPrice);
+    }
+
+    private void setReadOrder() {
+        Map<String, Integer> orderMenu;
+        try {
+            orderMenu = InputView.readOrder();
+            this.orderMenu.setUserOrder(orderMenu);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+            setReadOrder();
+        }
+    }
+}

리뷰: MainController가 크게 컨트롤(객체내 데이터를 수정 및 저장)하는 모델은 orderMenu인 것 같아보입니다. 즉 클래스 이름이 orderController이면 Model과 Controller간의 역할 의존성에 더 맞는 작명일 것 같습니다
@@ -0,0 +1,79 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Benefit {
+    private int orderDate;
+    private int[] categoryCount;
+    Map<String, Integer> benefits;
+
+    public Benefit(int orderDate, int[] categoryCount, int totalPrice) {
+        this.orderDate = orderDate;
+        this.categoryCount = categoryCount;
+        benefits = new HashMap<>();
+        if (totalPrice < Constant.MIN_BENEFIT_PRICE.get()) {
+            return;
+        }
+        christmasBenefit();
+        weekBenefit();
+        starBenefit();
+        if (totalPrice >= Constant.PRESENT_COST.get()) {
+            presentBenefit();
+        }
+    }
+
+    public Map<String, Integer> getBenefits() {
+        return this.benefits;
+    }
+
+    public int getTotalBenefitPrice() {
+        int totalBenefitPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.benefits.entrySet()) {
+            int benefit = entry.getValue();
+            totalBenefitPrice += benefit;
+        }
+        return totalBenefitPrice;
+    }
+
+    public int getPresentPrice() {
+        if (this.benefits.containsKey(Message.PRESENT_BENEFIT.get())) {
+            return Constant.CHAMPAIGN_PRICE.get();
+        }
+        return Constant.ZERO.get();
+    }
+
+    private void christmasBenefit() {
+        if (orderDate > Constant.CHRISTMAS_DAY.get()) {
+            return;
+        }
+        int benefit = Constant.THOUSAND.get() + (orderDate - Constant.ONE.get()) * Constant.HUNDRED.get();
+        benefits.put(Message.D_DAY_BENEFIT.get(), benefit);
+    }
+
+    private void weekBenefit() {
+        if (orderDate % Constant.WEEKDAYS.get() == Constant.FRIDAY.get()
+                || orderDate % Constant.WEEKDAYS.get() == Constant.SATURDAY.get()) {
+            int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.MAINMENU.get()];
+            benefits.put(Message.WEEKEND_BENEFIT.get(), benefit);
+            return;
+        }
+        int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.DESSERT.get()];
+        benefits.put(Message.WEEKDAY_BENEFIT.get(), benefit);
+    }
+
+    private void starBenefit() {
+        if (orderDate != Constant.CHRISTMAS_DAY.get()
+                && orderDate % Constant.WEEKDAYS.get() != Constant.SUNDAY.get()) {
+            return;
+        }
+        benefits.put(Message.STAR_BENEFIT.get(), Constant.THOUSAND.get());
+    }
+
+    private void presentBenefit() {
+        benefits.put(Message.PRESENT_BENEFIT.get(), Constant.CHAMPAIGN_PRICE.get());
+    }
+}

리뷰: 전체적으로 함수분리가 잘 돼있어서 함수당 라인이 짧은 편이네요! 굉장히 가독성 좋은 코드가 된 것 같습니다!
@@ -0,0 +1,39 @@
+package christmas.util;
+
+public enum Constant {
+    NOT_IN_MENU(-1),
+    EPPETIZER(0),
+    MAINMENU(1),
+    DESSERT(2),
+    BEVERAGE(3),
+    CATEGORY_COUNT(4),
+    ZERO(0),
+    ONE(1),
+    THOUSAND(1000),
+    HUNDRED(100),
+    CHRISTMAS_DAY(25),
+    MIN_BENEFIT_PRICE(10000),
+    PRESENT_COST(120000),
+    CHAMPAIGN_PRICE(25000),
+    WEEKDAYS(7),
+    FRIDAY(1),
+    SATURDAY(2),
+    SUNDAY(3),
+    EVENT_PRICE(2023),
+    SANTA(20000),
+    TREE(10000),
+    STAR(5000),
+    MAX_MENU_COUNT(20),
+    KEY_INDEX(0),
+    VALUE_INDEX(1);
+
+    private final int value;
+
+    Constant(int value) {
+        this.value = value;
+    }
+
+    public int get() {
+        return this.value;
+    }
+}

리뷰: 상수들을 enum으로 관리하시는 것은 좋은 포인트인 것 같습니다. 하지만 constant에 모든 상수를 다 넣어버리시면 개별 상수를 수정하거나 변경해야 할 때 찾기 어려워질 것 같아요. enum을 종류별로, 문맥별로 분리하시는 것을 추천 드려요.
@@ -0,0 +1,79 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Benefit {
+    private int orderDate;
+    private int[] categoryCount;
+    Map<String, Integer> benefits;
+
+    public Benefit(int orderDate, int[] categoryCount, int totalPrice) {
+        this.orderDate = orderDate;
+        this.categoryCount = categoryCount;
+        benefits = new HashMap<>();
+        if (totalPrice < Constant.MIN_BENEFIT_PRICE.get()) {
+            return;
+        }
+        christmasBenefit();
+        weekBenefit();
+        starBenefit();
+        if (totalPrice >= Constant.PRESENT_COST.get()) {
+            presentBenefit();
+        }
+    }
+
+    public Map<String, Integer> getBenefits() {
+        return this.benefits;
+    }
+
+    public int getTotalBenefitPrice() {
+        int totalBenefitPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.benefits.entrySet()) {
+            int benefit = entry.getValue();
+            totalBenefitPrice += benefit;
+        }
+        return totalBenefitPrice;
+    }
+
+    public int getPresentPrice() {
+        if (this.benefits.containsKey(Message.PRESENT_BENEFIT.get())) {
+            return Constant.CHAMPAIGN_PRICE.get();
+        }
+        return Constant.ZERO.get();
+    }
+
+    private void christmasBenefit() {
+        if (orderDate > Constant.CHRISTMAS_DAY.get()) {
+            return;
+        }
+        int benefit = Constant.THOUSAND.get() + (orderDate - Constant.ONE.get()) * Constant.HUNDRED.get();
+        benefits.put(Message.D_DAY_BENEFIT.get(), benefit);
+    }
+
+    private void weekBenefit() {
+        if (orderDate % Constant.WEEKDAYS.get() == Constant.FRIDAY.get()
+                || orderDate % Constant.WEEKDAYS.get() == Constant.SATURDAY.get()) {
+            int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.MAINMENU.get()];
+            benefits.put(Message.WEEKEND_BENEFIT.get(), benefit);
+            return;
+        }
+        int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.DESSERT.get()];
+        benefits.put(Message.WEEKDAY_BENEFIT.get(), benefit);
+    }
+
+    private void starBenefit() {
+        if (orderDate != Constant.CHRISTMAS_DAY.get()
+                && orderDate % Constant.WEEKDAYS.get() != Constant.SUNDAY.get()) {
+            return;
+        }
+        benefits.put(Message.STAR_BENEFIT.get(), Constant.THOUSAND.get());
+    }
+
+    private void presentBenefit() {
+        benefits.put(Message.PRESENT_BENEFIT.get(), Constant.CHAMPAIGN_PRICE.get());
+    }
+}

리뷰: 실제 애플리케이션에서 배열 보다는 리스트나, 맵, 셋 등 컬렉션 객체를 사용한다고 해요. 그 이유는 지난 주차 피드백을 보면 배열보다 좀 더 편리한 여러 API들을 제공하기 때문인데요. 이외에도 컬렉션이 선호되는 이유는 이펙티브 자바 등에서도 언급되어 있습니다.
https://incheol-jung.gitbook.io/docs/study/effective-java/undefined-3/2020-03-20-effective-28item
@@ -0,0 +1,68 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.ErrorMessage;
+import christmas.util.Utility;
+import christmas.util.Validator;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.List;
+
+public class OrderMenu {
+    private final List<Map<String, Integer>> menu;
+
+    private int orderDate;
+    private Map<String, Integer> userOrder;
+
+    public OrderMenu() {
+        menu = new ArrayList<>(List.of(
+                // EPPETIZER 0
+                Map.of("양송이수프", 6000, "타파스", 5500, "시저샐러드", 8000),
+                // MAINMENU 1
+                Map.of("티본스테이크", 55000, "바비큐립", 54000, "해산물파스타", 35000, "크리스마스파스타", 25000),
+                // DESSERT 2
+                Map.of("초코케이크", 15000, "아이스크림", 5000),
+                // BEVERAGE 3
+                Map.of("제로콜라", 3000, "레드와인", 60000, "샴페인", 25000)
+        ));
+    }
+
+    public int getOrderDate() {
+        return this.orderDate;
+    }
+
+    public Map<String, Integer> getUserOrder() {
+        return this.userOrder;
+    }
+
+    public int getTotalPrice() {
+        int totalPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            int price = menu.get(category).get(entry.getKey());
+            totalPrice += price * entry.getValue();
+        }
+        return totalPrice;
+    }
+
+    public int[] getCategoryCount() {
+        int[] categoryCount = new int[Constant.CATEGORY_COUNT.get()];
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            categoryCount[category] += entry.getValue();
+        }
+        return categoryCount;
+    }
+
+    public void setOrderDate(int date) {
+        this.orderDate = date;
+    }
+
+    public void setUserOrder(Map<String, Integer> userOrder) {
+        if (Validator.validateMenu(userOrder, this.menu)) {
+            throw new IllegalArgumentException(ErrorMessage.ORDER_ERROR.get());
+        }
+        this.userOrder = userOrder;
+    }
+}

리뷰: 메뉴 이름과 가격의 경우 하드 코딩하기보다 enum 등으로 분리하여 관리하는 것이 좋을 것 같습니다.
@@ -0,0 +1,39 @@
+package christmas.util;
+
+public enum Constant {
+    NOT_IN_MENU(-1),
+    EPPETIZER(0),
+    MAINMENU(1),
+    DESSERT(2),
+    BEVERAGE(3),
+    CATEGORY_COUNT(4),
+    ZERO(0),
+    ONE(1),
+    THOUSAND(1000),
+    HUNDRED(100),
+    CHRISTMAS_DAY(25),
+    MIN_BENEFIT_PRICE(10000),
+    PRESENT_COST(120000),
+    CHAMPAIGN_PRICE(25000),
+    WEEKDAYS(7),
+    FRIDAY(1),
+    SATURDAY(2),
+    SUNDAY(3),
+    EVENT_PRICE(2023),
+    SANTA(20000),
+    TREE(10000),
+    STAR(5000),
+    MAX_MENU_COUNT(20),
+    KEY_INDEX(0),
+    VALUE_INDEX(1);
+
+    private final int value;
+
+    Constant(int value) {
+        this.value = value;
+    }
+
+    public int get() {
+        return this.value;
+    }
+}

리뷰: 상수를 하나의 enum에 관리하신것 같은데, enum을 좀 분리해보면 어떨까요? 관련성이 없느 상수들끼리 한군데 몰려있다보니 어색하게 느껴집니다
@@ -0,0 +1,68 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.ErrorMessage;
+import christmas.util.Utility;
+import christmas.util.Validator;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.List;
+
+public class OrderMenu {
+    private final List<Map<String, Integer>> menu;
+
+    private int orderDate;
+    private Map<String, Integer> userOrder;
+
+    public OrderMenu() {
+        menu = new ArrayList<>(List.of(
+                // EPPETIZER 0
+                Map.of("양송이수프", 6000, "타파스", 5500, "시저샐러드", 8000),
+                // MAINMENU 1
+                Map.of("티본스테이크", 55000, "바비큐립", 54000, "해산물파스타", 35000, "크리스마스파스타", 25000),
+                // DESSERT 2
+                Map.of("초코케이크", 15000, "아이스크림", 5000),
+                // BEVERAGE 3
+                Map.of("제로콜라", 3000, "레드와인", 60000, "샴페인", 25000)
+        ));
+    }
+
+    public int getOrderDate() {
+        return this.orderDate;
+    }
+
+    public Map<String, Integer> getUserOrder() {
+        return this.userOrder;
+    }
+
+    public int getTotalPrice() {
+        int totalPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            int price = menu.get(category).get(entry.getKey());
+            totalPrice += price * entry.getValue();
+        }
+        return totalPrice;
+    }
+
+    public int[] getCategoryCount() {
+        int[] categoryCount = new int[Constant.CATEGORY_COUNT.get()];
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            categoryCount[category] += entry.getValue();
+        }
+        return categoryCount;
+    }
+
+    public void setOrderDate(int date) {
+        this.orderDate = date;
+    }
+
+    public void setUserOrder(Map<String, Integer> userOrder) {
+        if (Validator.validateMenu(userOrder, this.menu)) {
+            throw new IllegalArgumentException(ErrorMessage.ORDER_ERROR.get());
+        }
+        this.userOrder = userOrder;
+    }
+}

리뷰: menu를 list에 관리하셨군요
정답은 없는것 같다만 우테코에서 enum을 사용하라고 권장했으니 이런 메뉴들은 enum에서 관리하면 좀 더 좋지 않을까 생각이 듭니다!
@@ -0,0 +1,68 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.ErrorMessage;
+import christmas.util.Utility;
+import christmas.util.Validator;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.List;
+
+public class OrderMenu {
+    private final List<Map<String, Integer>> menu;
+
+    private int orderDate;
+    private Map<String, Integer> userOrder;
+
+    public OrderMenu() {
+        menu = new ArrayList<>(List.of(
+                // EPPETIZER 0
+                Map.of("양송이수프", 6000, "타파스", 5500, "시저샐러드", 8000),
+                // MAINMENU 1
+                Map.of("티본스테이크", 55000, "바비큐립", 54000, "해산물파스타", 35000, "크리스마스파스타", 25000),
+                // DESSERT 2
+                Map.of("초코케이크", 15000, "아이스크림", 5000),
+                // BEVERAGE 3
+                Map.of("제로콜라", 3000, "레드와인", 60000, "샴페인", 25000)
+        ));
+    }
+
+    public int getOrderDate() {
+        return this.orderDate;
+    }
+
+    public Map<String, Integer> getUserOrder() {
+        return this.userOrder;
+    }
+
+    public int getTotalPrice() {
+        int totalPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            int price = menu.get(category).get(entry.getKey());
+            totalPrice += price * entry.getValue();
+        }
+        return totalPrice;
+    }
+
+    public int[] getCategoryCount() {
+        int[] categoryCount = new int[Constant.CATEGORY_COUNT.get()];
+        for (Map.Entry<String, Integer> entry : this.userOrder.entrySet()) {
+            int category = Utility.getCategory(entry.getKey(), menu);
+            categoryCount[category] += entry.getValue();
+        }
+        return categoryCount;
+    }
+
+    public void setOrderDate(int date) {
+        this.orderDate = date;
+    }
+
+    public void setUserOrder(Map<String, Integer> userOrder) {
+        if (Validator.validateMenu(userOrder, this.menu)) {
+            throw new IllegalArgumentException(ErrorMessage.ORDER_ERROR.get());
+        }
+        this.userOrder = userOrder;
+    }
+}

리뷰: 클래스명은 OrderMenu인데 orderDate를 인스턴스 변수로 관리하는게 조금 어색하게 느껴집니다. 
클래스 분리를 통해 orderDate와 관련한 클래스를 만들거나, OrderMenu의 클래스명이 메뉴와 날짜를 다 포함하게끔 생각이 들게끔 변경해보면 어떨까요?
@@ -0,0 +1,47 @@
+package christmas.controller;
+
+import java.util.Map;
+
+import christmas.view.*;
+import christmas.model.*;
+
+public class MainController {
+    private OrderMenu orderMenu;
+
+    public MainController() {
+        orderMenu = new OrderMenu();
+    }
+
+    public void run() {
+        orderMenu.setOrderDate(InputView.readDate());
+        setReadOrder();
+
+        OutputView.printPreview(orderMenu.getOrderDate());
+        OutputView.printOrder(orderMenu.getUserOrder());
+        int totalPrice = orderMenu.getTotalPrice();
+        OutputView.printTotalPrice(totalPrice);
+        OutputView.printPresent(totalPrice);
+        benefitControl(totalPrice);
+    }
+
+    private void benefitControl(int totalPrice) {
+        Benefit benefit = new Benefit(orderMenu.getOrderDate(), orderMenu.getCategoryCount(), totalPrice);
+        OutputView.printBenefits(benefit.getBenefits());
+
+        int totalBenefitPrice = benefit.getTotalBenefitPrice();
+        OutputView.printTotalBenefitPrice(totalBenefitPrice);
+        OutputView.printTotalPayment(totalPrice - totalBenefitPrice + benefit.getPresentPrice());
+        OutputView.printEventBadge(totalBenefitPrice);
+    }
+
+    private void setReadOrder() {
+        Map<String, Integer> orderMenu;
+        try {
+            orderMenu = InputView.readOrder();
+            this.orderMenu.setUserOrder(orderMenu);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+            setReadOrder();
+        }
+    }
+}

리뷰: 사실 제가 엄청 오래 찾아보고 고민한 부분이긴 한데 보통 사용하는 방식은 잘 몰라서 제가 생각한 대로 했습니다. 개인적으로 생각한 View 클래스는 상태를 갖고 있지 않고 인스턴스화를 할 필요가 없는 것 같아서 스태틱 클래스나 싱글톤 패턴을 주로 사용한다고 봤었는데, 과제에서 View를 상속할 일은 없을 것 같아서 스태틱 클래스로 구현했습니다. 일반적으로는 싱글톤 패턴을 사용하는 걸까요?
@@ -0,0 +1,39 @@
+package christmas.util;
+
+public enum Constant {
+    NOT_IN_MENU(-1),
+    EPPETIZER(0),
+    MAINMENU(1),
+    DESSERT(2),
+    BEVERAGE(3),
+    CATEGORY_COUNT(4),
+    ZERO(0),
+    ONE(1),
+    THOUSAND(1000),
+    HUNDRED(100),
+    CHRISTMAS_DAY(25),
+    MIN_BENEFIT_PRICE(10000),
+    PRESENT_COST(120000),
+    CHAMPAIGN_PRICE(25000),
+    WEEKDAYS(7),
+    FRIDAY(1),
+    SATURDAY(2),
+    SUNDAY(3),
+    EVENT_PRICE(2023),
+    SANTA(20000),
+    TREE(10000),
+    STAR(5000),
+    MAX_MENU_COUNT(20),
+    KEY_INDEX(0),
+    VALUE_INDEX(1);
+
+    private final int value;
+
+    Constant(int value) {
+        this.value = value;
+    }
+
+    public int get() {
+        return this.value;
+    }
+}

리뷰: enum의 사용 방법을 잘 몰랐던 것 같아요 감사합니다!
@@ -0,0 +1,47 @@
+package christmas.controller;
+
+import java.util.Map;
+
+import christmas.view.*;
+import christmas.model.*;
+
+public class MainController {
+    private OrderMenu orderMenu;
+
+    public MainController() {
+        orderMenu = new OrderMenu();
+    }
+
+    public void run() {
+        orderMenu.setOrderDate(InputView.readDate());
+        setReadOrder();
+
+        OutputView.printPreview(orderMenu.getOrderDate());
+        OutputView.printOrder(orderMenu.getUserOrder());
+        int totalPrice = orderMenu.getTotalPrice();
+        OutputView.printTotalPrice(totalPrice);
+        OutputView.printPresent(totalPrice);
+        benefitControl(totalPrice);
+    }
+
+    private void benefitControl(int totalPrice) {
+        Benefit benefit = new Benefit(orderMenu.getOrderDate(), orderMenu.getCategoryCount(), totalPrice);
+        OutputView.printBenefits(benefit.getBenefits());
+
+        int totalBenefitPrice = benefit.getTotalBenefitPrice();
+        OutputView.printTotalBenefitPrice(totalBenefitPrice);
+        OutputView.printTotalPayment(totalPrice - totalBenefitPrice + benefit.getPresentPrice());
+        OutputView.printEventBadge(totalBenefitPrice);
+    }
+
+    private void setReadOrder() {
+        Map<String, Integer> orderMenu;
+        try {
+            orderMenu = InputView.readOrder();
+            this.orderMenu.setUserOrder(orderMenu);
+        } catch (IllegalArgumentException e) {
+            System.out.println(e.getMessage());
+            setReadOrder();
+        }
+    }
+}

리뷰: 다시 보니까 MainController가 적절한 이름이 아닌 것 같네요, 보통 모델과 컨트롤러의 관계가 1대 1로 이루어진다고 보면 되는 걸까요?
@@ -0,0 +1,39 @@
+package christmas.util;
+
+public enum Constant {
+    NOT_IN_MENU(-1),
+    EPPETIZER(0),
+    MAINMENU(1),
+    DESSERT(2),
+    BEVERAGE(3),
+    CATEGORY_COUNT(4),
+    ZERO(0),
+    ONE(1),
+    THOUSAND(1000),
+    HUNDRED(100),
+    CHRISTMAS_DAY(25),
+    MIN_BENEFIT_PRICE(10000),
+    PRESENT_COST(120000),
+    CHAMPAIGN_PRICE(25000),
+    WEEKDAYS(7),
+    FRIDAY(1),
+    SATURDAY(2),
+    SUNDAY(3),
+    EVENT_PRICE(2023),
+    SANTA(20000),
+    TREE(10000),
+    STAR(5000),
+    MAX_MENU_COUNT(20),
+    KEY_INDEX(0),
+    VALUE_INDEX(1);
+
+    private final int value;
+
+    Constant(int value) {
+        this.value = value;
+    }
+
+    public int get() {
+        return this.value;
+    }
+}

리뷰: 상수처리에만 급급해서 분리하지 못했는데 지금 보니 가독성 측면에서도 좋지 않은 것 같네요. 이 부분은 꼭 수정해야겠습니다 감사합니다!
@@ -0,0 +1,79 @@
+package christmas.model;
+
+import christmas.util.Constant;
+import christmas.util.Message;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Benefit {
+    private int orderDate;
+    private int[] categoryCount;
+    Map<String, Integer> benefits;
+
+    public Benefit(int orderDate, int[] categoryCount, int totalPrice) {
+        this.orderDate = orderDate;
+        this.categoryCount = categoryCount;
+        benefits = new HashMap<>();
+        if (totalPrice < Constant.MIN_BENEFIT_PRICE.get()) {
+            return;
+        }
+        christmasBenefit();
+        weekBenefit();
+        starBenefit();
+        if (totalPrice >= Constant.PRESENT_COST.get()) {
+            presentBenefit();
+        }
+    }
+
+    public Map<String, Integer> getBenefits() {
+        return this.benefits;
+    }
+
+    public int getTotalBenefitPrice() {
+        int totalBenefitPrice = Constant.ZERO.get();
+        for (Map.Entry<String, Integer> entry : this.benefits.entrySet()) {
+            int benefit = entry.getValue();
+            totalBenefitPrice += benefit;
+        }
+        return totalBenefitPrice;
+    }
+
+    public int getPresentPrice() {
+        if (this.benefits.containsKey(Message.PRESENT_BENEFIT.get())) {
+            return Constant.CHAMPAIGN_PRICE.get();
+        }
+        return Constant.ZERO.get();
+    }
+
+    private void christmasBenefit() {
+        if (orderDate > Constant.CHRISTMAS_DAY.get()) {
+            return;
+        }
+        int benefit = Constant.THOUSAND.get() + (orderDate - Constant.ONE.get()) * Constant.HUNDRED.get();
+        benefits.put(Message.D_DAY_BENEFIT.get(), benefit);
+    }
+
+    private void weekBenefit() {
+        if (orderDate % Constant.WEEKDAYS.get() == Constant.FRIDAY.get()
+                || orderDate % Constant.WEEKDAYS.get() == Constant.SATURDAY.get()) {
+            int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.MAINMENU.get()];
+            benefits.put(Message.WEEKEND_BENEFIT.get(), benefit);
+            return;
+        }
+        int benefit = Constant.EVENT_PRICE.get() * categoryCount[Constant.DESSERT.get()];
+        benefits.put(Message.WEEKDAY_BENEFIT.get(), benefit);
+    }
+
+    private void starBenefit() {
+        if (orderDate != Constant.CHRISTMAS_DAY.get()
+                && orderDate % Constant.WEEKDAYS.get() != Constant.SUNDAY.get()) {
+            return;
+        }
+        benefits.put(Message.STAR_BENEFIT.get(), Constant.THOUSAND.get());
+    }
+
+    private void presentBenefit() {
+        benefits.put(Message.PRESENT_BENEFIT.get(), Constant.CHAMPAIGN_PRICE.get());
+    }
+}

리뷰: 위 코드에서는 배열만으로 해결이 가능해서 배열로 처리했는데 올려주신 링크를 보니까 컬렉션 ArrayList의 장점이 가변 길이만은 아니었군요. 많이 배우고 갑니다!