@@ -0,0 +1,98 @@
+package christmas.service;
+
+import static christmas.constants.event.EventRule.MAX_MENU_AMOUNT;
+import static christmas.constants.menu.MenuType.DRINKS;
+import static christmas.exception.ErrorCode.INVALID_MENU_ORDER;
+
+import christmas.constants.menu.Menu;
+import christmas.constants.menu.MenuType;
+import christmas.dto.SingleMenu;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+public class MenuService {
+    private final Map<Menu, Integer> menuScript;
+
+    public MenuService() {
+        this.menuScript = new EnumMap<>(Menu.class);
+    }
+
+    public void order(List<SingleMenu> singleMenus) {
+        validate(singleMenus);
+        singleMenus.forEach(singleOrder -> {
+            Menu menu = Menu.from(singleOrder.menu());
+            menuScript.put(menu, singleOrder.amount());
+        });
+    }
+
+    public int getOrderPrice() {
+        return menuScript.keySet()
+                .stream()
+                .mapToInt(menu -> menu.getPrice() * menuScript.get(menu))
+                .sum();
+    }
+
+    private void validate(List<SingleMenu> singleMenus) {
+        validateDuplicate(singleMenus);
+        validatePerMenuAmount(singleMenus);
+        validateOnlyDrink(singleMenus);
+        validateTotalMenuAmount(singleMenus);
+    }
+
+    private void validateDuplicate(List<SingleMenu> singleMenus) {
+        int count = (int) getMenuStream(singleMenus)
+                .distinct()
+                .count();
+
+        if (count != singleMenus.size()) {
+            throw new IllegalArgumentException(INVALID_MENU_ORDER.getMessage());
+        }
+    }
+
+    private void validateOnlyDrink(List<SingleMenu> singleMenus) {
+        int drinks = (int) getMenuStream(singleMenus)
+                .filter(menu -> menu.getMenuType() == DRINKS)
+                .count();
+
+        if (drinks > 0 && drinks == singleMenus.size()) {
+            throw new IllegalArgumentException(INVALID_MENU_ORDER.getMessage());
+        }
+    }
+
+    private Stream<Menu> getMenuStream(List<SingleMenu> singleMenus) {
+        return singleMenus.stream()
+                .map(singleOrder -> Menu.from(singleOrder.menu()));
+    }
+
+    private void validatePerMenuAmount(List<SingleMenu> singleMenus) {
+        boolean present = singleMenus.stream()
+                .anyMatch(singleOrder -> singleOrder.amount() < 1);
+        if (present) {
+            throw new IllegalArgumentException(INVALID_MENU_ORDER.getMessage());
+        }
+    }
+
+    private void validateTotalMenuAmount(List<SingleMenu> singleMenus) {
+        int totalAmount = singleMenus.stream()
+                .mapToInt(SingleMenu::amount)
+                .sum();
+        if (totalAmount >= MAX_MENU_AMOUNT.getValue()) {
+            throw new IllegalArgumentException(INVALID_MENU_ORDER.getMessage());
+        }
+    }
+
+    public int getAmountByMenu(MenuType menuType) {
+        return menuScript.keySet()
+                .stream()
+                .filter(target -> target.getMenuType() == menuType)
+                .mapToInt(menuScript::get)
+                .sum();
+    }
+
+    public Map<Menu, Integer> getMenuScript() {
+        return Collections.unmodifiableMap(menuScript);
+    }
+}

리뷰: stream을 int로 캐스팅하는  것이 이해가 되지 않습니다.