본 캠프_18일차

졸용·2025년 3월 13일

TIL

목록 보기
19/144

⭐ 두 번째 개인 프로젝트 - 키오스크

< 중간 점검 후의 To do List >

✅ 캡슐화 → (수정 필요)

✅ 메뉴를 모두 한 번에 출력하지 않고, 카테고리 선택하여 출력하기

✅ 선택한 제품 출력하기

⬜ 카테고리 선택 옵션에 [ ORDER MENU ] 추가

  • ☑️ 1번, 2번, 0번 카테고리 옵션 출력과 함께 아래 옵션 추가

  • ☑️ 3. Orders | 장바구니를 확인 후 주문합니다.

  • ◻️ 4. Cancel | 진행중인 주문을 취소합니다.

✅ 장바구니

  • ☑️ 선택한 메뉴 장바구니에 담기 (추가 / 취소)

  • ☑️ '추가' 입력 시 추가된 제품 정보 출력 & ORDER MENU (장바구니 목록) 함께 출력

  • ☑️ '취소' 입력 시 다시 메뉴 출력하고 메뉴 선택 입력 받기

⬜ 구매하기

⭐ 중간점검 수정본 - 장바구니

⭐ MenuItem 클래스

package secondproject;

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

public class MenuItem {

    // 필드 선언
    private final String name;
    private final double price;
    private final String description;

    // 게터
    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

    public String getDescription() {
        return description;
    }

    // 메뉴 아이템을 생성할 때 생성하는 생성자
    // MenuItem 객체를 생성할 때 이름, 가격, 설명을 받아서 필드에 저장
    public MenuItem(String name, double price, String description) {
        this.name = name;
        this.price = price;
        this.description = description;
    }

    // 버거 항목을 리스트에 추가하는 메서드
    public static List<MenuItem> BurgerMenu() {  // 버거 메뉴 항목들을 생성하여 List<MenuItem> 형태로 반환
        List<MenuItem> Burgers = new ArrayList<>();  // 여러 가지 버거 메뉴를 생성하여 리스트에 추가

        Burgers.add(new MenuItem("Bulgogi Burger", 4.7, "마요네즈, 양파, 레터스, 불고기소스, 불고기패티가 토핑된 불고기버거"));
        Burgers.add(new MenuItem("Shrimp Burger", 4.7, "타르타르 소스, 새우 패티, 양상추, 사우전드 아일랜드 드레싱이 토핑된 새우버거"));
        Burgers.add(new MenuItem("Cheese Burger", 5.2, " 머스타드 소스, 마요네즈, 저민 양파, 저민 피클, 치즈, 쇠고기 패티가 토핑된 치즈버거"));
        Burgers.add(new MenuItem("Chicken Burger", 4.0, "닭다리살패티, 데리야키소스, 양상추, 마요네즈, 머스타드가 토핑된 치킨버거"));
        Burgers.add(new MenuItem("Hanwoo Bulgogi Burger", 8.6, "마요네즈, 양파, 레터스, 불고기소스, 한우패티로 구성된 한우불고기버거"));

        return Burgers;  // 위에서 추가한 메뉴들을 리스트에 반환
    }

    // 음료 항목을 리스트에 추가하는 메서드
    public static List<MenuItem> DrinkMenu() {
        List<MenuItem> Drinks = new ArrayList<>();

        Drinks.add(new MenuItem("Pepsi Cola", 2.0, "콜라"));
        Drinks.add(new MenuItem("Pepsi Cola Zero Sugar", 2.0, "제로 콜라"));
        Drinks.add(new MenuItem("Chilsung Cider", 1.7, "사이다"));
        Drinks.add(new MenuItem("Cafe Americano", 2.5, "아메리카노"));
        Drinks.add(new MenuItem("Lemonade", 2.7, "레몬에이드"));

        return Drinks;
    }
}

// ================= To do List =================

// 세부 메뉴 속성 가지는 클래스
// List를 선언하여 여러 메뉴 추가 -> List<MenuItem> menuItems = new ArrayList<>();

// 이름, 가격, 설명 필드 선언하여 관리

// 구조에 맞게 함수를 선언해놓고 가져다 사용

// ================= 수정 과정에서 뺀 메서드 =================

// 세터
//    public void setName(String name) {
//        this.name = name;
//    }
//
//    public void setPrice(double price) {
//        this.price = price;
//    }
//
//    public void setDescription(String description) {
//        this.description = description;
//    }

// =======================================================

⭐ Menu 클래스

package secondproject;

import java.util.List;

public class Menu {

    public String name;

    // 메뉴 항목 저장할 리스트
    private List<MenuItem> menuItems;  // 객체들의 리스트 (각 카테고리의 메뉴 항목들을 저장)

    // 게터
    public List<MenuItem> getMenuItems() {
        return menuItems;
    }

    // 생성자 (메뉴 항목 받아서 각 카테고리의 메뉴 항목 초기화)
    public Menu(String name) {  // 메뉴 객체 생성할 때 카테고리 이름 받아오기
        this.name = name;

        // 메뉴 항목 리스트 불러오기
        if (name.equals("버거 메뉴")) {
            this.menuItems = MenuItem.BurgerMenu();
        } else if (name.equals("음료 메뉴")) {
            this.menuItems = MenuItem.DrinkMenu();
        }
    }

    // 메뉴 항목 출력 메서드
    public void printMenuItem() {
        System.out.println("[ " + name + " ]");
        for (int i = 0; i < menuItems.size(); i++) {
            MenuItem items = menuItems.get(i);
            System.out.println((i + 1) + ". " + items.getName() + " | " + items.getPrice() + " | " + items.getDescription());
        }
    }

    // 메뉴 크기 계산 메서드
    // 해당 메뉴의 항목 개수를 반환하기 위해
    public int MenuSize() {
        return menuItems.size();
    }
}

// ================= To do List =================

// MenuItem 클래스를 관리하는 클래스
// 카테고리 이름 필드 추가 -> 버거 메뉴, 음료 메뉴, 디저트 메뉴 등 각 카테고리 내에 여러 MenuItem 을 포함

// MenuItem 클래스를 List로 관리

// Menu 객체 생성하면서 카테고리 이름 설정 (버거, 음료, 디저트 등등)
// Menu 클래스 내 있는 List<MenuItem> 에 MenuItem 객체 생성하면서 삽입

// List에 포함된 MenuItem을 순차적으로 보여주는 함수
// List를 리턴하는 함수

// 구조에 맞게 함수를 선언해놓고 가져다 사용

// ================= 수정 과정에서 뺀 메서드 =================

// 메뉴 총 크기 계산 메서드
// public static int TotalMenuSize(Menu burgerMenu, Menu drinkMenu) {
//        return burgerMenu.MenuSize() + drinkMenu.MenuSize();
//    }

// =======================================================

⭐ kiosk 클래스

package secondproject;

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

public class Kiosk {

    Scanner sc = new Scanner(System.in);

    int choice;


    // 키오스크 시작 메서드
    public void start() {
        System.out.println("키오스크를 시작합니다.");
        System.out.println();
    }

    // 카테고리 배열로 관리
    private final String[] Categories = {"버거 메뉴", "음료 메뉴"};

    // 각 카테고리의 Menu 객체 생성
    Menu burgerMenu = new Menu("버거 메뉴");
    Menu drinkMenu = new Menu("음료 메뉴");

    // 사용자에게 카테고리 번호를 입력받는 메서드
    public void getUserCategoryChoice() {
        int choice;

        while (true) {
            System.out.println("[[ Lotteria Menu ]]");
            System.out.println();
            System.out.println("[ 카테고리 ]");

            // 카테고리 선택지 출력
            for (int i = 0; i < Categories.length; i++) {
                System.out.println("[ " + (i + 1) + ". " + Categories[i] + " ]");
            }

            System.out.println("[ 0. 종료 ]");
            System.out.println("원하는 카테고리의 번호를 입력해주세요: ");
            String input = sc.nextLine();

            try {
                choice = Integer.parseInt(input);

                if (choice == 0) {
                    System.out.println("프로그램을 종료합니다.");
                    System.exit(0);
                }
                if (choice >= 1 && choice <= Categories.length) {
                    // 카테고리 선택 후 해당 카테고리 출력하는 연산 로직
                    // 상황 연산자(? :) → (조건) ? 조건이 참일 때 실행할 코드 : 조건이 거짓일 때 실행할 코드
                    Menu selectedCategory = (choice == 1) ? burgerMenu : drinkMenu;
                    // choice가 1이면 참 → 버거메뉴 출력, 2면 거짓 → 음료 메뉴 출력

                    // 선택된 카테고리 출력
                    selectedCategory.printMenuItem();
                    // 선택된 카테고리의 메뉴로 이동
                    getUserChoice();
                    break;  // 선택이 완료되면 반복문 종료
                } else {
                    System.out.println("유효하지 않은 번호입니다. 선택지 중에서 번호를 골라 입력해주세요.");
                    System.out.println();
                }
            } catch (NumberFormatException a) {
                System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
                System.out.println();
            }
        }
    }

    // 사용자에게 메뉴 번호 입력 받는 메서드
    public int getUserChoice() {

        while (true) {
            // 번호 입력 받기
            System.out.println();
            System.out.println("원하는 제품의 번호를 입력해주세요 (0을 입력하면 뒤로가기): ");
            String input = sc.nextLine();

            try {
                // 입력 받은 (문자 형태)숫자를 숫자로 인식하기 위해 형 변환
                choice = Integer.parseInt(input);

                // 0 입력시 뒤로가기
                if (choice == 0) {
                    System.out.println("카테고리 선택으로 돌아갑니다.");
                    System.out.println();
                    getUserCategoryChoice();
                    break;
                }

                if (choice > 0 && choice <= burgerMenu.MenuSize()) {
                    // 선택된 제품 출력하는 연산 로직
                    MenuItem selectedMenu = burgerMenu.getMenuItems().get(choice - 1);  // 0부터 시작하기 때문에 -1
                    printSelectedMenu(selectedMenu);
                    shoppingCart(selectedMenu);
                } else if (choice > 0 && choice <= drinkMenu.MenuSize()) {
                    MenuItem selectedMenu = drinkMenu.getMenuItems().get(choice - 1);
                    printSelectedMenu(selectedMenu);
                    shoppingCart(selectedMenu);
                } else {  // 메뉴 번호가 유효한지 확인
                    System.out.println("유효하지 않은 번호입니다. 선택지 중에서 번호를 골라 입력해주세요.");
                }

            } catch (NumberFormatException a) {
                System.out.println("잘못된 입력입니다. 숫자만 입력해주세요.");
            }
        } return choice;
    }

    // 선택한 메뉴를 출력하는 메서드
    public void printSelectedMenu(MenuItem selectedMenu) {
        System.out.println("선택한 메뉴는 다음과 같습니다:");
        System.out.println("메뉴명: " + selectedMenu.getName());
        System.out.println("가격: " + selectedMenu.getPrice());
        System.out.println("상세정보: " + selectedMenu.getDescription());
        System.out.println();
    }

    // 장바구니 담을 리스트 생성
    public List<MenuItem> orders = new ArrayList<>();

    // 장바구니 메서드
    public void shoppingCart(MenuItem selectedMenu) {
        // 장바구니에 담을지 물어보는 로직
        System.out.println("장바구니에 담으시겠습니싸? (추가 / 취소): ");
        String addToCart = sc.nextLine();

        if (addToCart.equals("추가")) {
            orders.add(selectedMenu);
            System.out.println(selectedMenu.getName() + " 가 장바구니에 추가되었습니다.");
            System.out.println();
            printShoppingCart();
        } else if (addToCart.equals("취소")) {
            System.out.println("취소되었습니다.");
            selectedCategory.printMenuItem();
            getUserChoice();
        } else {
            System.out.println("잘못된 입력입니다. '추가' 또는 '취소'를 입력하세요.");
        }
    }

    // 장바구니 담긴 목록 총 금액 계산해서 출력하는 메서드
    public void printShoppingCart() {
        if (orders.isEmpty()) {
            System.out.println("장바구니에 아무것도 없습니다. 먼저 메뉴를 선택해주세요.");
            return;
        }
        System.out.println("[ ORDER MENU ]");
        System.out.println();
        double totalPrice = 0;

        // ':' 향상된 for문 (shoppingCart에서 MenuItem 타입의 요소들을 하나씩 써내서 item에 담고 반복)
        for (MenuItem item : orders) {
            System.out.println(item.getName() + " | " + item.getPrice() + " | ");
            totalPrice += item.getPrice();
        }

        System.out.println("총 금액: " + totalPrice);
        System.out.println("주문하시겠습니까? (주문하기 / 취소): ");
        String order = sc.nextLine();

        if (order.equals("주문하기")) {
            System.out.println("주문이 완료되었습니다. 감사합니다.");
            orders.clear();  // 장바구니 초기화
        } else {
            System.out.println("주문이 취소되었습니다.");
        }
    }


}

// ================= To do List =================

// 프로그램 순서 및 흐름 제어를 담당하는 클래스
// 키오스크 실행 시 콘솔에 햄버거 메뉴 (with 선택번호) 출력, 종료 (with 선택번호) 함께 출력
// 사용자에게 숫자를 입력 받아 메뉴를 선택, 0을 입력하면 프로그램 종료
// 예외처리는 오류메시지 출력

// 스캐너 선언
// 반복문 시작

// List와 Menu 클래스 활용하여 상위 카테고리 메뉴 출력

// 카테고리 숫자 입력 받기

// 입력 받은 숫자가 올바르다면 인덱스로 활용하여 List에 접근하기
// List<Menu>에 인덱스로 접근하여 Menu만 추출할 수 있도록하기

// Menu가 가진 List<MenuItem>을 반복문을 활용하여 햄버거 메뉴 출력

// 주문할 메뉴 숫자 입력 받기
// 입력 받은 숫자가 올바르다면 인덱스로 활용해서 Menu가 가지고 있는 List<MenuItem>에 접근하기
// menu.getMenuItems().get(i); 같은 형식으로 하나씩 들어가서 얻어오기

// 장바구니: 메뉴를 선택/입력 시 장바구니에 추가할 지 물어보고, 입력값에 따라 추가/취소 처리, 메뉴는 한 번에 1개만 담기
// 장바구니에 담긴 모든 항목 출력, 합산하여 총 금액을 계산하고, “주문하기”를 누르면 장바구니를 초기화, ⭐장바구니 목록 수량도 출력

// ================= 수정 과정에서 뺀 메서드 =================

// 메뉴 총 크기 메서드 호출
//    public int menuSize() {
//        return Menu.TotalMenuSize(burgerMenu, drinkMenu);
//    }

// =======================================================

⭐ main 클래스

package secondproject;

public class Main {
    public static void main(String[] args) {

        Kiosk kiosk = new Kiosk();

        // 키오스크 시작 메서드 호출
        kiosk.start();

        // 카테고리 선택 메서드 호출
        kiosk.getUserCategoryChoice();

        // 메뉴 선택 메서드 호출
        kiosk.getUserChoice();
        System.out.println();

        // 장바구니 출력 메서드 호출
        kiosk.printShoppingCart();

    }
}

// ================= To do List =======================

// 시작 지점이 되는 클래스
// Main = User 라고 생각하기 (키오스크 시작하기, 카테고리 선택하기, 결제하기 등)

// Kiosk 객체 생성
// Kiosk 내 시작하는 함수 호출 -> 키오스크 프로그램을 시작하는 메서드 구현하고 -> start 함수 만들어서 관리

// 구현할 것등 : 캡슐화, 장바구니, 구매하기, 선택한 메뉴 출력되기

// ================= 수정 과정에서 뺀 메서드 =================

// kiosk.menuSize();

// =======================================================

⭐ 트러블슈팅

⚠️ Kiosk 클래스의 shoppingCart 메서드에서 else if 문제

selectedCategory.printMenuItem(); 이 부분이 선택된 카테고리의 메뉴를 불러오지 못 하는 문제 발생

문제 원인은 변수의 선언이 getUserCategoryChoice 메서드 안에 있어서 불러오지 못 하는 것으로 판단

➡️ 현재 선택된 카테고리 (burgerMenu 또는 drinkMenu)를 클래스 차원에서 관리하도록 public Menu selectedCategory; 코드 추가하고

이제 클래스 내에서 선택된 카테고리를 계속 추적하기 때문에 다른 메서드에서도 편하게 사용할 수 있다

➡️ getUserCategoryChoice 메서드에서 selectedCategory = (choice == 1) ? burgerMenu : drinkMenu; 수정해서 해결

selectedCategory는 이제 지역 변수로 선언할 필요가 없어졌다


⚠️ 장바구니 반복문 문제

장바구니 메서드에서 추가 / 취소 로직 부분에 유효하지 않은 문자 입력 시 오류 메시지 출력 후에 다시 추가 / 취소 입력 받지 않는 문제 발견

public void shoppingCart(MenuItem selectedMenu) {

        while (true) {

            // 선택한 메뉴 상세정보 출력하는 메서드호출
            printSelectedMenu();

            // 장바구니에 담을지 물어보는 로직
            System.out.println("장바구니에 담으시겠습니싸? (추가 / 취소): ");
            String addToCart = sc.nextLine();

            if (addToCart.equals("추가")) {
                orders.add(selectedMenu);
                System.out.println(selectedMenu.getName() + " 가 장바구니에 추가되었습니다.");
                System.out.println();
                printShoppingCart();
                break;
            } else if (addToCart.equals("취소")) {
                System.out.println("▶ 취소되었습니다 ◀");
                System.out.println();
                getUserChoice();
                break;
            } else {
                System.out.println("▶ 잘못된 입력입니다. '추가' 또는 '취소'를 입력하세요 ◀");
                System.out.println();
            }
        }
    }

➡️ shoppingCart 메서드에 while 문과 그 안에 적절한 위치에 루프를 끝내줄 break 로직을 추가하여 해결


⚠️ 출력되는 카테고리 범위 문제

카테고리 선택 → 메뉴 선택 → 해당 카테고리의 메뉴가 아닌 무조건 버거 카테고리의 메뉴가 출력되는 문제 발견

➡️ getUserChoice 메서드에서 selectedMenu 에 제대로 선택된 메뉴 값을 할당해주도록 수정해서 해결

if (choice > 0 && choice <= selectedCategory.MenuSize()) {
                    // 선택된 메뉴 항목을 selectedMenu에 할당
                    selectedMenu = selectedCategory.getMenuItems().get(choice - 1);  // 0부터 시작하기 때문에 -1
                    printSelectedMenu();
                    shoppingCart(selectedMenu);
                }

이렇게 수정하면 selectedMenu에 할당 할 메뉴를 버거 메뉴와 음료 메뉴를 따로 작성 할 필요가 없기 때문에 코드를 통합하면서 choice 의 번호 유효 범위도 각각의 메뉴 사이즈가 아닌 통일된 메뉴 사이즈로 수정했다

profile
꾸준한 공부만이 답이다

0개의 댓글