본문 바로가기

JAVA

[Java] Lv_4 & 5 키오스크 문제

 

요구사항

  • Menu 클래스 생성하기
    • ⬜ 설명 : MenuItem 클래스를 관리하는 클래스입니다. 예를 들어, 버거 메뉴, 음료 메뉴 등 각 카테고리 내에 여러 MenuItem을 포함합니다.
    • ⬜ List<MenuItem> 은 Kiosk 클래스가 관리하기에 적절하지 않으므로 Menu 클래스가 관리하도록 변경합니다.
    • ⬜ 여러 버거들을 포함하는 상위 개념 ‘버거’ 같은 카테고리 이름 필드를 갖습니다.
    • ⬜ 메뉴 카테고리 이름을 반환하는 메서드가 구현되어야 합니다.
  • ⬜ MenuItem, Menu 그리고 Kiosk 클래스의 필드에 직접 접근하지 못하도록 설정합니다.
  • ⬜ Getter와 Setter 메서드를 사용해 데이터를 관리합니다.
  • Lv4 & 5를 구현하면 터미널에 이렇게 보여집니다.
[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
1 <- // 1을 입력

[ BURGERS MENU ]
1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거
3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거
4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
0. 뒤로가기
2 <- // 2를 입력
선택한 메뉴: SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
0 <- // 0을 입력
프로그램을 종료합니다.

 

 


 

 

문제 풀이

Lv_1 ~ Lv_3에서 부분에 대한 설명은 생략하겠다.

 

Main

더보기
package com.example.kiosk.lv_4;

public class Main {
    public static void main(String[] args) {
        Kiosk kiosk = new Kiosk();

        kiosk.start();
    }
}
  • 기존에 있던 키오스크에 메뉴를 추가하는 기능을 menu 클래스에 정의하고 kiosk 생성자에서 추가하도록하였다.
  • 이로써 main에는 키오스크 객체를 생성하고 시작하는 메서드만 남게된다.

 

 

Kiosk

더보기
package com.example.kiosk.lv_4;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Kiosk {
    // 속성
    Menu menu = new Menu();

    // 생성자
    public Kiosk() {
        menu.addMenu(new Burger("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거", MenuType.BURGER));
        menu.addMenu(new Burger("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거", MenuType.BURGER));
        menu.addMenu(new Burger("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거", MenuType.BURGER));
        menu.addMenu(new Burger("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거", MenuType.BURGER));
        menu.addMenu(new Cake("CheeseCake", 10.4, "내가 제일 좋아하는 치즈 케이크", MenuType.CAKE));
    }

    // 기능
    // 키오스크 동작
    public void start() {
        int mainMenuInput;
        int menuInput;
        do {
            menu.showMainMenu();
            System.out.print("메뉴를 선택하세요 : ");
            mainMenuInput = userInput();

            if (mainMenuInput == 0) {
                System.out.println("종료합니다.");
                return;
            } else if (MenuType.values().length < mainMenuInput) {
                System.out.println("메뉴가 없습니다.");
                continue;
            } else if (mainMenuInput == -1) {
                continue;
            }

            System.out.println();
            menu.showMenu(mainMenuInput);
            System.out.print("메뉴를 선택하세요 : ");
            menuInput = userInput();

            if (menuInput == 0) {
                System.out.println();
                continue;
            }

            menu.showSelectedFood(mainMenuInput, menuInput);
        } while(true);
    }

    // 유저 메뉴 입력 받는 함수
    private int userInput() {
        Scanner scanner = new Scanner(System.in);
        try {
            return scanner.nextInt();
        } catch(InputMismatchException e) {
            System.out.println("올바른 값을 입력하세요.");
            scanner.nextLine();
            System.out.println();
            return -1;
        }
    }
}
  • 키오스크 생성자에서 음식 정보를 추가할 수 있게 변경하였다.
  • start() 메서드에서는 키오스크 전체 흐름이 정리되어있다.
  • 사용하지 않는 메서드는 없앴고 메뉴와 관련된 기능들은 Menu 클래스로 옮겼다.

 

 

Menu

더보기
package com.example.kiosk.lv_4;

import java.util.ArrayList;
import java.util.List;

public class Menu {
    // 속성
    List<List<MainMenu>> menuItems = new ArrayList<>();

    // 생성자
    public Menu() {
        for(MenuType menuType : MenuType.values()) {
            menuItems.add(new ArrayList<>());
        }
    }

    // 메뉴 추가하는 기능
    public void addMenu(MainMenu newFood) {
        menuItems.get(newFood.getMenuType().getNum()-1).add(newFood);
    }

    // 메인 메뉴 보여주는 기능
    public void showMainMenu() {
        int num = 1;
        System.out.println("[ MAIN MENU ]");
        System.out.println("0. 종료\t\t | 종료");
        for(MenuType type : MenuType.values()){
            System.out.println(num++ + ". " + type.name());
        }
    }


    // 메뉴 보여주는 기능
    public void showMenu(int input) {
        int num = 1;

        System.out.println("[ SHAKESHACK MENU ]");
        System.out.println("0. 뒤로가기\t\t");
        for (MainMenu menuItem : menuItems.get(input-1)) {
            System.out.println(num++ + ". "
                    + menuItem.getFood_name() + "\t | w "
                    + menuItem.getPrice() + " |\t"
                    + menuItem.getIngredients());
        }
    }


    // 메뉴 정보 제공
    public void showSelectedFood(int mainMenuInput, int menuInput) {
        try {
            System.out.println("선택한 메뉴 : "
                    + menuItems.get(mainMenuInput-1).get(menuInput-1).getFood_name() + "\t | w "
                    + menuItems.get(mainMenuInput-1).get(menuInput-1).getPrice() + " |\t"
                    + menuItems.get(mainMenuInput-1).get(menuInput-1).getIngredients());
        } catch (IndexOutOfBoundsException e) {
            System.out.println("음식이 존재하지 않습니다.");
        } finally {
            System.out.println();
        }
    }
}
  • menuItems는 메뉴의 배열을 저장할 수 있는 배열이다.
    (예: [["치즈버거", "치킨버거", ..], ["콜라", "사이다", ..], ["콘샐러드", "아이스크림", ..]])
  • 생성자 부분에서는 MenyType의 갯수만큼 배열을 생성하였다. 이렇게 하면 좋은 점은 다음과 같다.
    • MenuType이 늘어나도, 이 코드를 수정하여 하드코딩으로 배열을 선언할 필요가 없다. 즉, 수정에는 닫혀있고 확장에는 열있게 된다.
  • addMenu() 메서드는 MenuType에서 정의된 num값(인덱스)에 따라 menuItems에 저장된다. 이렇게 하면 좋은 점은 다음과 같다.
    • 내가 어떤 음식 객체를 생성하는지에 따라 그 배열에 알맞게 저장된다.
    • MenuType(enum)에 새로운 값이 추가되어도 enum의 값만 제대로 수정한다면, 알아서 전체 순서가 맞춰진다.

 

 

MenuType

더보기
package com.example.kiosk.lv_4;

public enum MenuType {
    BURGER("Burgers", 1),
    DRINK("Drinks", 2),
    DESSERT("Desserts",3),
    CAKE("Cakes",4);

    private final String type;
    private final int num;

    MenuType(String type, int num) {
        this.type = type;
        this.num = num;
    }

    public String getType() {
        return type;
    }

    public int getNum() {
        return num;
    }
}

 

 

 

MainMenu

더보기
package com.example.kiosk.lv_4;

public class MainMenu {
    private final String food_name;
    private final double price;
    private final String ingredients;
    private final MenuType menuType;

    public MainMenu(String food_name, double price, String ingredients, MenuType menuType) {
        this.food_name = food_name;
        this.price = price;
        this.ingredients = ingredients;
        this.menuType = menuType;
    }

    public String getFood_name() {
        return food_name;
    }

    public double getPrice() {
        return price;
    }

    public String getIngredients() {
        return ingredients;
    }

    public MenuType getMenuType() {
        return menuType;
    }
}
  • 각 음식은 동일한 속성, 생성자, 기능을 갖으므로 부모 객체를 만들었다.
  • Menu 클래스에서 배열에 저장할 때, 다형성을 이용해서 저장할 수 있게 해준다.

 

 

Burger

더보기
package com.example.kiosk.lv_4;

public class Burger extends MainMenu{

    public Burger(String food_name, double price, String ingredients, MenuType menuType) {
        super(food_name, price, ingredients, menuType);
    }
}

 

 

 

Drink

더보기
package com.example.kiosk.lv_4;

public class Drink extends MainMenu{

    public Drink(String food_name, double price, String ingredients, MenuType menuType) {
        super(food_name, price, ingredients, menuType);
    }
}

 

 

 

Dessert

더보기
package com.example.kiosk.lv_4;

public class Dessert extends MainMenu{

    public Dessert(String food_name, double price, String ingredients, MenuType menuType) {
        super(food_name, price, ingredients, menuType);
    }
}

 

'JAVA' 카테고리의 다른 글

[Java] 제네릭(Generic), 왜 사용할까?  (0) 2025.04.28
[Java] 도전 과제 Lv_1 키오스크  (0) 2025.04.26
[Java] Lv_3 키오스크  (0) 2025.04.24
[Java] Lv_2 키오스크  (1) 2025.04.24
[Java] Lv_1 키오스크  (0) 2025.04.24