ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,51 @@
+package christmas;
+
+import camp.nextstep.edu.missionutils.Console;
+import christmas.controller.EventController;
+import christmas.model.domain.event.strategy.ChristmasEventStrategy;
+import christmas.model.domain.event.EventRepository;
+import christmas.model.domain.event.strategy.EventStrategy;
+import christmas.model.domain.event.benefit.totaldiscount.ChristmasTotalDiscount;
+import christmas.model.service.ChristmasEventService;
+import christmas.model.util.Converter;
+import christmas.view.InputView;
+import christmas.view.OutputView;
+
+public class AppConfig {
+
+    public EventController getChristmasEventController() {
+        return new EventController(christmasEventService(), inputView(), outputView());
+    }
+
+    private InputView inputView() {
+        return new InputView();
+    }
+
+    private OutputView outputView() {
+        return new OutputView();
+    }
+
+    private ChristmasEventService christmasEventService() {
+        return new ChristmasEventService(converter(), eventRepository(), christmasEventStrategy());
+    }
+
+    private Converter converter() {
+        return new Converter();
+    }
+
+    private EventRepository eventRepository() {
+        return EventRepository.getEventRepository();
+    }
+
+    private EventStrategy christmasEventStrategy() {
+        return new ChristmasEventStrategy(christmasTotalDiscount());
+    }
+
+    private ChristmasTotalDiscount christmasTotalDiscount() {
+        return new ChristmasTotalDiscount();
+    }
+
+    public void endEvent() {
+        Console.close();
+    }
+}

리뷰: Spring의 AppConfig 방법을 떠올리게 하는 의존관계 주입 방법이군요!
인상적입니다 👍
@@ -1,7 +1,12 @@
 package christmas;
 
+import christmas.controller.EventController;
+
 public class Application {
     public static void main(String[] args) {
-        // TODO: 프로그램 구현
+        AppConfig appConfig = new AppConfig();
+        EventController christmasEventController = appConfig.getChristmasEventController();
+        christmasEventController.startEvent();
+        appConfig.endEvent();
     }
 }

리뷰: christmasEventController가 단일 메소드로 모든 비즈니스 로직을 담당하고 있어요.

이렇게 설계하면 Controller Layer 단위 테스트 = 통합 테스트로
이해할 수 있을 것 같은데, 적절한 테스트 방법일지 궁금해요
@@ -0,0 +1,30 @@
+package christmas.model.domain.dto;
+
+import christmas.model.domain.order.RequestOrder;
+import java.util.Collections;
+import java.util.List;
+
+public class RequestOrdersDto {
+
+    private final List<RequestOrder> requestOrders;
+    private final String ordersMessage;
+    private final int totalOrderPrice;
+
+    public RequestOrdersDto(List<RequestOrder> requestOrders, String ordersMessage, int totalOrderPrice) {
+        this.requestOrders = requestOrders;
+        this.ordersMessage = ordersMessage;
+        this.totalOrderPrice = totalOrderPrice;
+    }
+
+    public List<RequestOrder> getRequestOrders() {
+        return Collections.unmodifiableList(requestOrders);
+    }
+
+    public String getOrdersMessage() {
+        return ordersMessage;
+    }
+
+    public int getTotalOrderPrice() {
+        return totalOrderPrice;
+    }
+}

리뷰: DTO가 RequestOrder라는 모델을 필드값 자체에 그대로 갖고 있는 것 같아요!
이렇게 설계하신 이유가 있을까요?
@@ -0,0 +1,45 @@
+package christmas.model.domain.event.benefit.totaldiscount;
+
+import christmas.model.domain.date.Date;
+import christmas.model.domain.event.benefit.DiscountBenefit;
+import christmas.model.domain.event.discount.Discount;
+import christmas.model.domain.event.discount.ChristmasDiscountStrategies;
+import christmas.model.domain.order.RequestOrders;
+import java.util.List;
+import java.util.stream.Stream;
+
+public class ChristmasTotalDiscount implements TotalDiscount {
+    private final List<Discount> discounts;
+
+    public ChristmasTotalDiscount() {
+        discounts = ChristmasDiscountStrategies.getAllDiscountStrategy();
+    }
+
+    public static ChristmasTotalDiscount makeZeroTotalDiscount() {
+        return new ChristmasTotalDiscount();
+    }
+
+    @Override
+    public void applyDiscount(RequestOrders requestOrders, Date date) {
+        discounts.forEach(discount -> discount.calculateDiscountAmount(requestOrders, date));
+    }
+
+    @Override
+    public int calculateDiscountBenefit() {
+        return discounts.stream()
+                .mapToInt(Discount::getDiscountAmount)
+                .sum();
+    }
+
+    @Override
+    public DiscountBenefit makeDiscountBenefit() {
+        return new DiscountBenefit(calculateDiscountBenefit(), makeDiscountBenefitMessageStream());
+    }
+
+    @Override
+    public Stream<String> makeDiscountBenefitMessageStream() {
+        return discounts.stream()
+                .filter(Discount::isNotZero)
+                .map(Discount::toString);
+    }
+}

리뷰: 전체적으로 상속관계를 잘 활용해, 메소드 오버라이딩까지 예쁘게 활용하신 부분이 굉장히 인상깊었어요!
저도 응집도와 결합도를 고려하며, 상속 설계를 고민해 봐야겠어요!
잘 배우고 갑니다 :)
@@ -0,0 +1,14 @@
+const homeDao = require('../models/homeDao')
+
+const getTop9ByRating = async () => {
+    return await homeDao.getProductsByRating();
+};
+
+const getTop9BySales = async () => {
+    return await homeDao.getProductsBySales();
+};
+
+module.exports ={
+    getTop9ByRating,
+    getTop9BySales
+}
\ No newline at end of file

리뷰: top 9으로 고정값을 변수명에 정해 놓는 것보다 유연하게 외부 요청에 그때 그때 대응할 수 있게 변경해주세요!~
offset limit 값을 전달 받으면 쉽게 해결할 수 있는 문제 같아 보이네요!~
@@ -1,26 +1,30 @@
 import { CHAT_SORT_OPTIONS } from '@/constants/chat';
+import { User } from './user';
 
-export type SortType = keyof typeof CHAT_SORT_OPTIONS;
-
-export interface RoomResponse {
+export interface ChatRoom {
   chatId: string;
   chattingName: string;
+  description: string;
   host: string;
+  hostProfileImage: string;
   hasJoined: boolean;
+  unreadMessageCount: number;
   lastMessageTime: string;
   image: string;
-  unreadMessageCount: number;
   membersCount: number;
   totalMembersCount: number;
-  hostProfileImage: string;
-  description: string;
 }
 
-export interface ChattingResponse {
+export interface Chat {
   chatTitle: string;
   chatMessages: ChatMessage[];
 }
 
+export interface ChatOverview {
+  participants: Participant[];
+  album: ImageInfo[];
+}
+
 export interface ChatMessage {
   chatMessageId: string;
   images: string[];
@@ -31,20 +35,15 @@ export interface ChatMessage {
   unreadCount: number;
 }
 
-export interface ChatOverview {
-  participants: Participant[];
-  album: ImageInfo[];
-}
-
 export interface ImageInfo {
   images: string[];
   uploadDate: string;
   uploader: string;
 }
-export interface Participant {
-  user: string;
-  email: string;
-  description: string;
-  profileImage: string;
+
+export interface Participant
+  extends Pick<User, 'email' | 'profileImage' | 'nickname' | 'description'> {
   travelCount: number;
 }
+
+export type SortType = keyof typeof CHAT_SORT_OPTIONS;

리뷰: 공용 유저 타입과 겹치는 부분이 많은 것 같습니다. User 인터페이스 가져다가 쓰시면 좋을 것 같아요.
유틸리티 타입과 확장 이용하시면 될 것 같아요.
@@ -0,0 +1,50 @@
+export const THE_DATE = {
+  first: 1,
+  end: 31,
+  christmas: 25,
+};
+
+export const WEEK = {
+  sunday: 3,
+  monday: 4,
+  tuesday: 5,
+  wednesday: 6,
+  thursday: 0,
+  friday: 1,
+  saturday: 2,
+};
+
+export const MENU_NUMBER = {
+  minimum: 1,
+  maximum: 20,
+};
+
+export const ALL_MENU = [
+  { name: "양송이수프", price: 6000 },
+  { name: "타파스", price: 5500 },
+  { name: "시저샐러드", price: 8000 },
+
+  { name: "티본스테이크", price: 55000 },
+  { name: "바비큐립", price: 54000 },
+  { name: "해산물파스타", price: 35000 },
+  { name: "크리스마스파스타", price: 25000 },
+
+  { name: "초코케이크", price: 15000 },
+  { name: "아이스크림", price: 5000 },
+
+  { name: "제로콜라", price: 3000 },
+  { name: "레드와인", price: 60000 },
+  { name: "샴페인", price: 25000 },
+];
+
+export const MAIN = ["티본스테이크", "바비큐립", "해산물파스타", "크리스마스파스타"];
+
+export const DESSERT = ["초코케이크", "아이스크림"];
+
+export const BEVERAGE = ["제로콜라", "레드와인", "샴페인"];
+
+export const LEAST_AMOUNT = 10000;
+
+export const CHAMPAGNE_PRICE = 25000;
+
+export const BADGE_PRICE = { star: 5000, tree: 10000, santa: 20000 };

리뷰: 상수를 불변하는 값으로 사용하기 위해 Object.freeze 메소드를 통해 관리하셨다면 좋지 않았을까요?
작성하신 코드에서는 상수의 값이 변경될 위험이 있어보입니다 !
@@ -0,0 +1,44 @@
+import MenuSlider from "../domain/MenuSlider.js";
+import MenuList from "../domain/MenuList.js";
+import Date from "../domain/Date.js";
+import OutputView from "../views/OutputView.js";
+import InputView from "../views/InputView.js";
+
+class ChristmasPromotion {
+  #date;
+  #menuList;
+
+  constructor() {
+    this.#date = 0;
+    this.#menuList = [];
+  }
+  async inputDate() {
+    while (true) {
+      try {
+        const inputDate = await InputView.readDate();
+        return new Date(Number(inputDate));
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+  async inputMenus() {
+    while (true) {
+      try {
+        return new MenuList(await MenuSlider.getSlideMenu());
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+
+  async play() {
+    OutputView.printHello();
+    this.#date = await this.inputDate();
+    this.#menuList = await this.inputMenus();
+    OutputView.printPreviewText(this.#date);
+    OutputView.printAllBenefit(this.#date, this.#menuList);
+  }
+}
+
+export default ChristmasPromotion;

리뷰: 혹시 생성자에서 값을 따로 초기화 해주시는 이유가 있을까요?
생성자에서 값을 초기화하는 경우에는 각 인스턴스가 생성되는 시점에 어떠한 값을 기본값으로 가져아할 때에만 생성자에서 값을 할당한다고 생각하는데, 작성하신 코드같은 경우에는 클래스 필드에 선언하실 때 기본값을 지정해주셔도 괜찮지 않았을까 생각합니다!
@@ -0,0 +1,44 @@
+import MenuSlider from "../domain/MenuSlider.js";
+import MenuList from "../domain/MenuList.js";
+import Date from "../domain/Date.js";
+import OutputView from "../views/OutputView.js";
+import InputView from "../views/InputView.js";
+
+class ChristmasPromotion {
+  #date;
+  #menuList;
+
+  constructor() {
+    this.#date = 0;
+    this.#menuList = [];
+  }
+  async inputDate() {
+    while (true) {
+      try {
+        const inputDate = await InputView.readDate();
+        return new Date(Number(inputDate));
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+  async inputMenus() {
+    while (true) {
+      try {
+        return new MenuList(await MenuSlider.getSlideMenu());
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+
+  async play() {
+    OutputView.printHello();
+    this.#date = await this.inputDate();
+    this.#menuList = await this.inputMenus();
+    OutputView.printPreviewText(this.#date);
+    OutputView.printAllBenefit(this.#date, this.#menuList);
+  }
+}
+
+export default ChristmasPromotion;

리뷰: while문의 종료 조건이 따로 없는 것 같아 질문 남깁니다!
올바른 값이 입력되었을 때에는 while문이 종료되는건가요?
@@ -0,0 +1,44 @@
+import MenuSlider from "../domain/MenuSlider.js";
+import MenuList from "../domain/MenuList.js";
+import Date from "../domain/Date.js";
+import OutputView from "../views/OutputView.js";
+import InputView from "../views/InputView.js";
+
+class ChristmasPromotion {
+  #date;
+  #menuList;
+
+  constructor() {
+    this.#date = 0;
+    this.#menuList = [];
+  }
+  async inputDate() {
+    while (true) {
+      try {
+        const inputDate = await InputView.readDate();
+        return new Date(Number(inputDate));
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+  async inputMenus() {
+    while (true) {
+      try {
+        return new MenuList(await MenuSlider.getSlideMenu());
+      } catch (error) {
+        OutputView.printErrorMessage(error.message);
+      }
+    }
+  }
+
+  async play() {
+    OutputView.printHello();
+    this.#date = await this.inputDate();
+    this.#menuList = await this.inputMenus();
+    OutputView.printPreviewText(this.#date);
+    OutputView.printAllBenefit(this.#date, this.#menuList);
+  }
+}
+
+export default ChristmasPromotion;

리뷰: play 메소드에서 12월 할인 이벤트의 프로그램 흐름을 명확하게 볼 수 있어서 좋은 것 같습니다 👍
@@ -0,0 +1,47 @@
+import Discount from "./Discount.js";
+import { BADGE_PRICE, LEAST_AMOUNT } from "../constants/constant.js";
+
+class Benefit {
+  static getGiftMenu(menuList) {
+    return menuList.getTotalAmount() >= 120000 ? "샴페인 1개" : "없음";
+  }
+
+  static getBenefitsDetail(date, menuList) {
+    if (menuList.getTotalAmount() < LEAST_AMOUNT) return ["없음"];
+    const benefitsDetail = [];
+    Discount.addChristmasDiscount(benefitsDetail, date);
+    Discount.addWeekendDiscount(benefitsDetail, date, menuList);
+    Discount.addWeekdayDiscount(benefitsDetail, date, menuList);
+    Discount.addSpecialDiscount(benefitsDetail, date);
+    Discount.addEventGift(benefitsDetail, menuList);
+
+    return benefitsDetail.length === 0 ? ["없음"] : benefitsDetail;
+  }
+
+  static getTotalBenefitAmount(date, menuList) {
+    if (menuList.getTotalAmount() < LEAST_AMOUNT) return 0;
+    let totalBenefitAmount = 0;
+    totalBenefitAmount += Discount.getChristmasDiscountAmount(date);
+    totalBenefitAmount += Discount.getWeekendDiscountAmount(date, menuList);
+    totalBenefitAmount += Discount.getWeekdayDiscountAmount(date, menuList);
+    totalBenefitAmount += Discount.getSpecialDiscountAmount(date);
+    totalBenefitAmount += Discount.getEventGiftAmount(menuList);
+
+    return totalBenefitAmount;
+  }
+
+  static getPredictAmount(date, menuList) {
+    return this.getGiftMenu(menuList) === "샴페인 1개"
+      ? menuList.getTotalAmount() - this.getTotalBenefitAmount(date, menuList) + 25000
+      : menuList.getTotalAmount() - this.getTotalBenefitAmount(date, menuList);
+  }
+
+  static getEventBadge(date, menuList) {
+    const totalBenefitAmount = this.getTotalBenefitAmount(date, menuList);
+    if (totalBenefitAmount < BADGE_PRICE.star) return "없음";
+    if (totalBenefitAmount >= BADGE_PRICE.star && totalBenefitAmount < BADGE_PRICE.tree) return "별";
+    if (totalBenefitAmount >= BADGE_PRICE.tree && totalBenefitAmount < BADGE_PRICE.santa) return "트리";
+    if (totalBenefitAmount >= BADGE_PRICE.santa) return "산타";
+  }
+}
+export default Benefit;

리뷰: 객체간의 결합도가 높은 형태인 것 같습니다 !
혜택상세라는 배열 자체를 인자로 전달하는 것보다는 배열에서 필요한 데이터를 찾아서 메소드의 인자로 전달했으면 더 좋지 않았을까 개인적으로 생각합니다 :)

또 코드에서 보았을 때 인자로 전달되는 날짜(date)마다 다른 혜택이 적용되는 형태인 것 같습니다.
개인적으로 이런 경우에 클래스의 정적 메소드로 선언해서 인자로 전달받아서 사용하기보다는 인스턴스를 생성하는 시점에 기본 값으로 설정될 수 있도록 생성자에 date를 전달받아 데이터를 활용하는 방식으로 코드를 작성했을 것 같습니다 :)
@@ -0,0 +1,47 @@
+import Discount from "./Discount.js";
+import { BADGE_PRICE, LEAST_AMOUNT } from "../constants/constant.js";
+
+class Benefit {
+  static getGiftMenu(menuList) {
+    return menuList.getTotalAmount() >= 120000 ? "샴페인 1개" : "없음";
+  }
+
+  static getBenefitsDetail(date, menuList) {
+    if (menuList.getTotalAmount() < LEAST_AMOUNT) return ["없음"];
+    const benefitsDetail = [];
+    Discount.addChristmasDiscount(benefitsDetail, date);
+    Discount.addWeekendDiscount(benefitsDetail, date, menuList);
+    Discount.addWeekdayDiscount(benefitsDetail, date, menuList);
+    Discount.addSpecialDiscount(benefitsDetail, date);
+    Discount.addEventGift(benefitsDetail, menuList);
+
+    return benefitsDetail.length === 0 ? ["없음"] : benefitsDetail;
+  }
+
+  static getTotalBenefitAmount(date, menuList) {
+    if (menuList.getTotalAmount() < LEAST_AMOUNT) return 0;
+    let totalBenefitAmount = 0;
+    totalBenefitAmount += Discount.getChristmasDiscountAmount(date);
+    totalBenefitAmount += Discount.getWeekendDiscountAmount(date, menuList);
+    totalBenefitAmount += Discount.getWeekdayDiscountAmount(date, menuList);
+    totalBenefitAmount += Discount.getSpecialDiscountAmount(date);
+    totalBenefitAmount += Discount.getEventGiftAmount(menuList);
+
+    return totalBenefitAmount;
+  }
+
+  static getPredictAmount(date, menuList) {
+    return this.getGiftMenu(menuList) === "샴페인 1개"
+      ? menuList.getTotalAmount() - this.getTotalBenefitAmount(date, menuList) + 25000
+      : menuList.getTotalAmount() - this.getTotalBenefitAmount(date, menuList);
+  }
+
+  static getEventBadge(date, menuList) {
+    const totalBenefitAmount = this.getTotalBenefitAmount(date, menuList);
+    if (totalBenefitAmount < BADGE_PRICE.star) return "없음";
+    if (totalBenefitAmount >= BADGE_PRICE.star && totalBenefitAmount < BADGE_PRICE.tree) return "별";
+    if (totalBenefitAmount >= BADGE_PRICE.tree && totalBenefitAmount < BADGE_PRICE.santa) return "트리";
+    if (totalBenefitAmount >= BADGE_PRICE.santa) return "산타";
+  }
+}
+export default Benefit;

리뷰: 클래스의 메소드들을 정적 메소드로 선언해주신 이유가 있을까요?
@@ -0,0 +1,34 @@
+import { ERROR_MESSAGE } from "../constants/message.js";
+import { THE_DATE, WEEK } from "../constants/constant.js";
+
+class Date {
+  #theDate;
+
+  constructor(input) {
+    this.validDate(input);
+    this.#theDate = input;
+  }
+  validDate(input) {
+    const isNumber = /^[1-9]\d*$/;
+    if (!(isNumber.test(input) && input >= THE_DATE.first && input <= THE_DATE.end)) {
+      throw new Error(ERROR_MESSAGE.errorDate);
+    }
+  }
+
+  getDate() {
+    return this.#theDate;
+  }
+
+  getChristmasDiscount() {
+    return this.#theDate <= THE_DATE.christmas ? (this.#theDate - 1) * 100 + 1000 : 0;
+  }
+
+  getSpecialDiscount() {
+    return this.#theDate % 7 === WEEK.sunday || this.#theDate === THE_DATE.christmas ? 1000 : 0;
+  }
+
+  getDayOfWeek() {
+    return this.#theDate % 7;
+  }
+}
+export default Date;

리뷰: 값을 검증하는 메서드의 경우에는 '#' prefix를 통해 private method로 선언해 활용하는 게 객체의 캡슐화에 도움이 될 것 같습니다 :)
@@ -0,0 +1,55 @@
+import { WEEK, CHAMPAGNE_PRICE } from "../constants/constant.js";
+
+class Discount {
+  static addChristmasDiscount(benefitsDetail, date) {
+    if (date.getChristmasDiscount() !== 0) {
+      benefitsDetail.push(`크리스마스 디데이 할인: -${date.getChristmasDiscount().toLocaleString("ko-KR")}원`);
+    }
+  }
+
+  static addWeekendDiscount(benefitsDetail, date, menuList) {
+    if ((date.getDayOfWeek() === WEEK.friday || date.getDayOfWeek() === WEEK.saturday) && menuList.checkMainNumber() > 0) {
+      benefitsDetail.push(`주말 할인: -${(menuList.checkMainNumber() * 2023).toLocaleString("ko-KR")}원`);
+    }
+  }
+
+  static addWeekdayDiscount(benefitsDetail, date, menuList) {
+    if ((date.getDayOfWeek() >= WEEK.sunday || date.getDayOfWeek() === WEEK.thursday) && menuList.checkDessertNumber() > 0) {
+      benefitsDetail.push(`평일 할인: -${(menuList.checkDessertNumber() * 2023).toLocaleString("ko-KR")}원`);
+    }
+  }
+
+  static addSpecialDiscount(benefitsDetail, date) {
+    if (date.getSpecialDiscount() === 1000) {
+      benefitsDetail.push(`특별 할인: -${date.getSpecialDiscount().toLocaleString("ko-KR")}원`);
+    }
+  }
+
+  static addEventGift(benefitsDetail, menuList) {
+    if (menuList.getTotalAmount() >= 120000) {
+      benefitsDetail.push(`증정 이벤트: -${CHAMPAGNE_PRICE.toLocaleString("ko-KR")}원`);
+    }
+  }
+
+  static getChristmasDiscountAmount(date) {
+    return date.getChristmasDiscount();
+  }
+
+  static getWeekendDiscountAmount(date, menuList) {
+    return date.getDayOfWeek() === WEEK.friday || date.getDayOfWeek() === WEEK.saturday ? menuList.checkMainNumber() * 2023 : 0;
+  }
+
+  static getWeekdayDiscountAmount(date, menuList) {
+    return date.getDayOfWeek() >= WEEK.sunday || date.getDayOfWeek() === WEEK.thursday ? menuList.checkDessertNumber() * 2023 : 0;
+  }
+
+  static getSpecialDiscountAmount(date) {
+    return date.getSpecialDiscount();
+  }
+
+  static getEventGiftAmount(menuList) {
+    return menuList.getTotalAmount() >= 120000 ? CHAMPAGNE_PRICE : 0;
+  }
+}
+
+export default Discount;

리뷰: Discount 클래스가 여러개의 책임을 가지고 있는 것 같습니다.
개인적으로 Discount 클래스는 할인 금액만을 계산하고 OutputView에서 문자열로 할인 혜택 정보를 담아서 보여주어야 한다고 생각했는데, 이 클래스에서 할인 혜택 정보 자체를 반환하신 이유가 있으신가요??
@@ -0,0 +1,47 @@
+import { MENU_NUMBER, ALL_MENU } from "../constants/constant.js";
+import { ERROR_MESSAGE } from "../constants/message.js";
+
+class Menu {
+  #name;
+  #number;
+  #price;
+
+  constructor(name, number) {
+    this.validMenuName(name);
+    this.validMenuNumber(number);
+    this.#name = name;
+    this.#number = number;
+    this.#price = this.setPrice(name);
+  }
+  validMenuName(name) {
+    const menuNames = ALL_MENU.map((menu) => menu.name);
+    if (!menuNames.includes(name)) {
+      throw new Error(ERROR_MESSAGE.errorMenu);
+    }
+  }
+
+  validMenuNumber(number) {
+    const isNumber = /^[1-9]\d*$/;
+    if (!(isNumber.test(number) && number >= MENU_NUMBER.minimum)) {
+      throw new Error(ERROR_MESSAGE.errorMenu);
+    }
+  }
+
+  setPrice(name) {
+    const foundMenu = ALL_MENU.find((menu) => menu.name === name);
+    return foundMenu.price;
+  }
+
+  getName() {
+    return this.#name;
+  }
+
+  getNumber() {
+    return this.#number;
+  }
+
+  getPrice() {
+    return this.#price;
+  }
+}
+export default Menu;

리뷰: 메소드에서 map 메서드와 include 메서드를 통해 전달받은 메뉴가 존재하는 메뉴인지 확인하고 있는 것 같습니다 !
이 경우에는 some 메소드를 활용해서 간단하게 표현할 수 있을 것 같습니다!
```js
if (!ALL_MENU.some((menu) => menu.name === name)) {
  throw new Error(ERROR_MESSAGE.errorMenu);
}
```
@@ -0,0 +1,27 @@
+import InputView from "../views/InputView.js";
+import Menu from "./Menu.js";
+import { ERROR_MESSAGE } from "../constants/message.js";
+
+class MenuSlider {
+  static async getSlideMenu() {
+    const menus = await InputView.readMenu();
+    const splitMenus = menus.split(",");
+    const menuList = [];
+
+    splitMenus.forEach((menu) => {
+      this.checkMenuFormat(menu);
+      let [name, number] = menu.split("-");
+      menuList.push(new Menu(name.trim(), Number(number)));
+    });
+
+    return menuList;
+  }
+
+  static checkMenuFormat(menu) {
+    let [name, number] = menu.split("-");
+    if (!(name && number)) {
+      throw new Error(`${ERROR_MESSAGE.errorMenu}`);
+    }
+  }
+}
+export default MenuSlider;

리뷰: 메뉴 형식 검사하는 메소드가 직관적어서 이해하기가 편한 것 같습니다 배워갑니다👍
@@ -0,0 +1,50 @@
+export const THE_DATE = {
+  first: 1,
+  end: 31,
+  christmas: 25,
+};
+
+export const WEEK = {
+  sunday: 3,
+  monday: 4,
+  tuesday: 5,
+  wednesday: 6,
+  thursday: 0,
+  friday: 1,
+  saturday: 2,
+};
+
+export const MENU_NUMBER = {
+  minimum: 1,
+  maximum: 20,
+};
+
+export const ALL_MENU = [
+  { name: "양송이수프", price: 6000 },
+  { name: "타파스", price: 5500 },
+  { name: "시저샐러드", price: 8000 },
+
+  { name: "티본스테이크", price: 55000 },
+  { name: "바비큐립", price: 54000 },
+  { name: "해산물파스타", price: 35000 },
+  { name: "크리스마스파스타", price: 25000 },
+
+  { name: "초코케이크", price: 15000 },
+  { name: "아이스크림", price: 5000 },
+
+  { name: "제로콜라", price: 3000 },
+  { name: "레드와인", price: 60000 },
+  { name: "샴페인", price: 25000 },
+];
+
+export const MAIN = ["티본스테이크", "바비큐립", "해산물파스타", "크리스마스파스타"];
+
+export const DESSERT = ["초코케이크", "아이스크림"];
+
+export const BEVERAGE = ["제로콜라", "레드와인", "샴페인"];
+
+export const LEAST_AMOUNT = 10000;
+
+export const CHAMPAGNE_PRICE = 25000;
+
+export const BADGE_PRICE = { star: 5000, tree: 10000, santa: 20000 };

리뷰: 과제를 수행하면서 object.freeze를 사용할 지 말지 고민을 해봤는데 역시 사용하는게 좋았을 것 같네요!
다음부터는 사용해서 관리해 봐야겠어요! 감사합니다!