개별과제 : 키오스크 제작 (+ 트러블 슈팅)

커비·2024년 11월 28일
0

과제 해결

목록 보기
6/9

❗ 개별과제

핵심목표 : 자바 문법의 실습과 객체 지향 개념의 적용
이 버전에서는 자바의 클래스 개념을 이해하고 객체 지향 설계를 활용해 키오스크를 구현합니다. 다시 한 번 자바 문법의 실습과 객체 지향 개념의 적용을 익힐 수 있습니다.


✅ 작업 기록

기말고사와 겹치는 바람에 바로 작업하지 못하고 2일 전으로 임박해서 작업을 시작하게 되었다.
주어진 5단계까지 무난하게 잘 해나갈 수 있을지 살짝 걱정이 앞서지만 최선을 다해 작업해보려고 한다!

1️⃣ 단계 '기본적인 키오스크를 프로그래밍해보자'

❗ 필수 기능 가이드

  • 요구사항이 가지는 의도
  • 입력 처리와 간단한 흐름 제어를 복습합니다. (프로그래밍 검증)
  • Scanner 활용법, 조건문, 반복문을 재확인하며 입력 데이터를 처리하는 방법 강화
    
  • 햄버거 메뉴 출력 및 선택하기
  • Scanner를 사용하여 여러 햄버거 메뉴를 출력합니다.
  • 제시된 메뉴 중 입력받은 숫자에 따라 다른 로직을 실행하는 코드를 작성합니다.
  • 반복문을 이용해서 특정 번호가 입력되면 프로그램을 종료합니다.

Kiosk.java

package com.example.kiosk;

import java.util.Scanner;

public class Kiosk {
    // 생성자
    private String menuIntro;
    private String bugerName;
    private String menuAll;

    private boolean menuStart;

    // 사용자 입력 객체 생성
    Scanner scanner = new Scanner(System.in);

    public void run() {
        menuStart = true;
        while (menuStart) {
            // 안내 및 메뉴 출력
            System.out.println(System.lineSeparator() + "=============== Kirby's Buger ===============");
            System.out.println("view : 메뉴판 확인 | save : 메뉴 등록 | exit : 종료");
            menuIntro = scanner.nextLine();

            switch (menuIntro) {
                // 키오스크 종료
                case "exit":
                    System.out.println("커비버거 키오스크를 종료합니다!");
                    System.exit(0);
                    break;
                // 키오스크 메뉴 등록
                case "save":
                    System.out.println("커비버거 메뉴를 등록합니다.");
                    menuStart = !menuStart;
                    break;
                // 키오스크 메뉴
                case "view":
                    menuAll = scanner.nextLine();
                    System.out.println("[ Kirby's Buger Menu]");
                    System.out.println("1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거");
                    System.out.println("2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거");
                    System.out.println("3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거");
                    System.out.println("4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거");
                    break;
            }
        }

        // 메뉴 이름 입력
        System.out.println("메뉴 이름을 입력하세요 : ");
        bugerName = scanner.nextLine();
    }

}

main.java

package com.example.kiosk;

public class Main {
    public static void main(String[] args) {
        // 프로그램 실행
        Kiosk kiosk = new Kiosk();
        kiosk.run();
    }
}

zoom 강의를 다시 들어보니 1단계에서는 sout 만으로 보이게 하라고 하셔서 그렇게 작업해보았다. 이게 맞나? 라는 생각이 들 정도로 허접스러운 코드같지만.. 가장 간결한 것 같았다. (입력한 메뉴가 아닌, 입력해놓은 메뉴를 보여주는 것이니까!)

구글 커밋 컨벤션에 대해 꼼꼼히 살펴보고 적합하게 작성해서 커밋 + 푸쉬를 해보았다!

다음 날, 뭔가 이 느낌이 아닌 것 같아서 다시 살펴보니 눈에 밟히는 부분이 있었다.

  • 제시된 메뉴 중 입력받은 숫자에 따라 다른 로직을 실행하는 코드를 작성합니다.
  • 반복문을 이용해서 특정 번호가 입력되면 프로그램을 종료합니다.

바로 이 부분이다. 다시 수정해야겠다고 생각이 들었다.
저장했는데 날아가버렸다. 젠장.......ㅋㅋ..........


2️⃣ 단계 '객체 지향 설계를 적용해 햄버거 메뉴를 클래스로 관리하기'

❗ 필수 기능 가이드

  • 요구사항이 가지는 의도
  • 객체 지향 개념을 학습하고, 데이터를 구조적으로 관리하며 프로그램을 설계하는 방법을 익힙니다.
  • 햄버거 메뉴를 MenuItem 클래스와 List를 통해 관리합니다.
    
  • MenuItem 클래스 생성하기
  • 설명 : 개별 음식 항목을 관리하는 클래스입니다. 현재는 햄버거만 관리합니다.
  • 클래스는 이름, 가격, 설명 필드를 갖습니다.
  • main 함수에서 MenuItem 클래스를 활용하여 햄버거 메뉴를 출력합니다.
  • MenuItem 객체 생성을 통해 이름, 가격, 설명을 세팅합니다.
  • 키워드: new
  • List를 선언하여 여러 MenuItem을 추가합니다.
  • List<MenuItem> menuItems = new ArrayList<>();
  • 반복문을 활용해 menuItems를 탐색하면서 하나씩 접근합니다.

2단계 작업에서 1시간 정도 머리를 감싸맸다. 해보다 이건 아닌 것 같고 이렇게 쓰면 유지보수에 안좋을 것 같다는 생각이 들고 해서 나온 결과다..!!

Main.java

package kioskLv2;

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

메인에서 달라지는 건 없다. kiosk 프로그램을 실행하는 용도로만 사용하기 때문이다.

Kiosk.java

package kioskLv2;

import java.util.Scanner;

// 키오스크의 메인 로직 관리
public class Kiosk {
    private Scanner scanner;
    private Menu menu;
    private boolean isRunning;

    // 생성자
    public Kiosk() {
        scanner = new Scanner(System.in);
        menu = new Menu();
        isRunning = true;
    }

    // 키오스크 실행
    public void run() {
        while (isRunning) {
            showMainMenu();
            String input = scanner.nextLine();

            switch (input.toLowerCase()) {
                case "1":
                case "2":
                case "3":
                case "4":
                    showMenuDetails(Integer.parseInt(input) - 1);
                    break;
                case "view":
                    menu.displayMenu();
                    break;
                case "save":
                    addCustomMenuItem();
                    break;
                case "exit":
                    System.out.println("키오스크를 종료합니다.");
                    isRunning = false;
                    break;
                default:
                    System.out.println("올바른 입력이 아닙니다. 다시 시도하세요.");
                    break;
            }
        }
    }

    // 메인 메뉴 출력
    private void showMainMenu() {
        System.out.println("\n=============== Kirby's Burger Kiosk ===============");
        System.out.println("1 : 1번 메뉴 보기 | 2 : 2번 메뉴 보기 | 3 : 3번 메뉴 보기 | 4 : 4번 메뉴 보기");
        System.out.println("view : 전체 메뉴 보기 | save : 새 메뉴 추가 | exit : 종료");
        System.out.println("===================================================");
        System.out.print("선택: ");
    }

    // 메뉴 상세 정보 출력
    private void showMenuDetails(int menuIndex) {
        MenuItem item = menu.getMenuItem(menuIndex);
        if (item != null) {
            System.out.println("\n=============== 메뉴 상세 정보 ===============");
            item.printMenuItem(menuIndex + 1);
            System.out.println("==========================================");
        } else {
            System.out.println("해당 메뉴는 존재하지 않습니다.");
        }
    }

    // 사용자 정의 메뉴 추가
    private void addCustomMenuItem() {
        System.out.print("메뉴 이름: ");
        String name = scanner.nextLine();
        System.out.print("메뉴 가격: ");
        double price = Double.parseDouble(scanner.nextLine());
        System.out.print("메뉴 설명: ");
        String description = scanner.nextLine();

        menu.addMenuItem(new MenuItem(name, price, description));
        System.out.println("새로운 메뉴가 추가되었습니다!");
    }
}
package kioskLv2;

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

// 여러 메뉴 항목을 관리
public class Menu {
    private List<MenuItem> menuItems;

    // 생성자
    public Menu() {
        menuItems = new ArrayList<>();
        initializeMenu();
    }

    // 초기 메뉴 추가
    private void initializeMenu() {
        addMenuItem(new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거"));
        addMenuItem(new MenuItem("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"));
        addMenuItem(new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"));
        addMenuItem(new MenuItem("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거"));
    }

    // 메뉴 추가
    public void addMenuItem(MenuItem item) {
        menuItems.add(item);
    }

    // 전체 메뉴 출력
    public void displayMenu() {
        System.out.println("=============== 메뉴 리스트 ===============");
        for (int i = 0; i < menuItems.size(); i++) {
            menuItems.get(i).printMenuItem(i + 1);
        }
        System.out.println("==========================================");
    }

    // 메뉴 가져오기
    public MenuItem getMenuItem(int index) {
        if (index >= 0 && index < menuItems.size()) {
            return menuItems.get(index);
        }
        return null;
    }
}
package kioskLv2;

// 단일 메뉴 항목을 관리
public class MenuItem {
    private String menuName;
    private double menuPrice;
    private String menuDescription;

    // 생성자
    public MenuItem(String menuName, double menuPrice, String menuDescription) {
        this.menuName = menuName;
        this.menuPrice = menuPrice;
        this.menuDescription = menuDescription;
    }

    // Getter 메서드
    public String getMenuName() {
        return menuName;
    }

    public double getMenuPrice() {
        return menuPrice;
    }

    public String getMenuDescription() {
        return menuDescription;
    }

    // 메뉴 정보 출력
    public void printMenuItem(int menuNum) {
        System.out.println(menuNum + ". " + menuName + " | W " + menuPrice + " | " + menuDescription);
    }
}

원래 Menu.java는 2단계에서 처리를 요구하지 않는다.
하지만 MenuItem을 작업하다가 갑갑하고 이렇게 하면 안되나? 싶은 생각이 들어서 활용했다.


3️⃣ 단계 '객체 지향 설계를 적용해 순서 제어를 클래스로 관리하기'

❗ 필수 기능 가이드

  • 요구사항이 가지는 의도
  • 객체 지향 개념을 학습하고, 데이터를 구조적으로 관리하며 프로그램을 설계하는 방법을 익힙니다.
  • main 함수에서 관리하던 전체 순서 제어를 Kiosk 클래스를 통해 관리합니다.
    
  • Kiosk 클래스 생성하기
  • 설명: 키오스크 프로그램의 메뉴를 관리하고 사용자 입력을 처리하는 클래스입니다.
  • MenuItem을 관리하는 리스트가 필드를 갖습니다.
  • main 함수에서 관리하던 입력과 반복문 로직은 이제 start 함수를 만들어 관리합니다.
  • List<MenuItem> menuItemsKiosk 클래스 생성자를 통해 값을 할당합니다.
  • Kiosk 객체를 생성하고 사용하는 main 함수에서 객체를 생성할 때 값을 넘겨줍니다.
  • 요구사항에 부합하는지 검토
  • 키오스크 프로그램을 시작하는 메서드가 구현되어야 합니다.
  • 콘솔에 햄버거 메뉴를 출력합니다.
  • 사용자의 입력을 받아 메뉴를 선택하거나 프로그램을 종료합니다.
  • 유효하지 않은 입력에 대해 오류 메시지를 출력합니다.
  • 0을 입력하면 프로그램이 ‘뒤로가기’되거나 ‘종료’됩니다.

3단계 작업에서는 0을 입력했을 때 '뒤로가기'하는 부분만 추가하면 될 것 같아서 // 메뉴 상세정보 출력 부분에 코드를 추가했다.

Kiosk.java

package com.example.kiosk;

import java.util.Scanner;

// 키오스크의 메인 로직을 관리
public class Kiosk {
    private Scanner scanner;
    private Menu menu;
    private boolean isRunning;

    // 생성자
    public Kiosk() {
        scanner = new Scanner(System.in);
        menu = new Menu();
        isRunning = true;
    }

    // 키오스크 실행
    public void run() {
        while (isRunning) {
            showMainMenu();
            String input = scanner.nextLine().toLowerCase(); // 소문자로 변환

            switch (input) {
                case "1":
                case "2":
                case "3":
                case "4":
                    showMenuDetails(Integer.parseInt(input) - 1);
                    break;
                case "view":
                    menu.displayMenu();
                    break;
                case "save":
                    addCustomMenuItem();
                    break;
                case "exit":
                    System.out.println("키오스크를 종료합니다.");
                    isRunning = false;
                    break;
                default:
                    System.out.println("올바른 입력이 아닙니다. 다시 시도하세요.");
                    break;
            }
        }
    }

    // 메인 메뉴 출력
    private void showMainMenu() {
        System.out.println("\n=============== Kirby's Burger Kiosk ===============");
        System.out.println("1 : 1번 메뉴 보기 | 2 : 2번 메뉴 보기 | 3 : 3번 메뉴 보기 | 4 : 4번 메뉴 보기");
        System.out.println("view : 전체 메뉴 보기 | save : 새 메뉴 추가 | exit : 종료");
        System.out.println("===================================================");
        System.out.print("선택 : ");
    }

    // 메뉴 상세 정보 출력
    private void showMenuDetails(int menuIndex) {
        while (true) {
            MenuItem item = menu.getMenuItem(menuIndex);
            if (item != null) {
                System.out.println("\n=============== 메뉴 상세 정보 ===============");
                item.printMenuItem(menuIndex + 1);
                System.out.println("==========================================");
                System.out.println("뒤로가려면 'back'을 입력하세요.");
                System.out.print("선택 : ");
                String input = scanner.nextLine().toLowerCase();
                if (input.equals("back")) {
                    return; // 메인 메뉴로 돌아가기
                } else {
                    System.out.println("올바른 입력이 아닙니다. 다시 시도하세요.");
                }
            } else {
                System.out.println("해당 메뉴는 존재하지 않습니다.");
                return; // 메인 메뉴로 돌아가기
            }
        }
    }

    // 사용자 정의 메뉴 추가
    private void addCustomMenuItem() {
        System.out.print("메뉴 이름: ");
        String name = scanner.nextLine();
        System.out.print("메뉴 가격: ");
        double price = Double.parseDouble(scanner.nextLine());
        System.out.print("메뉴 설명: ");
        String description = scanner.nextLine();

        menu.addMenuItem(new MenuItem(name, price, description));
        System.out.println("새로운 메뉴가 추가되었습니다!");
    }
}

4️⃣ 단계 '객체 지향 설계를 적용해 음식 메뉴와 주문 내역을 클래스 기반으로 관리하기'

❗ 필수 기능 가이드

  • Menu 클래스 생성하기
  • 설명 : MenuItem 클래스를 관리하는 클래스입니다.
    예를 들어, 버거 메뉴, 음료 메뉴 등 각 카테고리 내에 여러 MenuItem을 포함합니다.
  • List<MenuItem>Kiosk 클래스가 관리하기에 적절하지 않으므로 Menu 클래스가 관리하도록 변경합니다.
  • 여러 버거들을 포함하는 상위 개념 ‘버거’ 같은 카테고리 이름 필드를 갖습니다.
  • 메뉴 카테고리 이름을 반환하는 메서드가 구현되어야 합니다.

내가 작업해놓은 방향과 조금 달라져서 헛웃음 한 번과 함께 수정을 진행했다.
그렇게 어려운 작업이 되진 않았고 Menu.java에서 각 카테고리를 관리할 수 있도록 List를 추가하고 Kiosk.java에는 상세정보 보기와 뒤로가기를 모두 실행할 수 있도록 작성했다.

package com.example.kiosk;

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

// 여러 카테고리 메뉴를 관리
public class Menu {
    private List<MenuItem> burgers;
    private List<MenuItem> drinks;
    private List<MenuItem> desserts;

    // 생성자
    public Menu() {
        burgers = new ArrayList<>();
        drinks = new ArrayList<>();
        desserts = new ArrayList<>();
        initializeMenu();
    }

    // 초기 메뉴 설정
    private void initializeMenu() {
        initializeBurgersMenu();
        initializeDrinksMenu();
        initializeDessertsMenu();
    }

    // 초기 버거 메뉴 추가
    private void initializeBurgersMenu() {
        burgers.add(new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거"));
        burgers.add(new MenuItem("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"));
        burgers.add(new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"));
        burgers.add(new MenuItem("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거"));
    }

    // 초기 음료 메뉴 추가
    private void initializeDrinksMenu() {
        drinks.add(new MenuItem("Sprite", 1.9, "스프라이트"));
        drinks.add(new MenuItem("Grape Ade", 5.0, "포도 에이드"));
        drinks.add(new MenuItem("Budweiser", 4.5, "버드와이저"));
        drinks.add(new MenuItem("Americano", 3.0, "아메리카노"));
    }

    // 초기 디저트 메뉴 추가
    private void initializeDessertsMenu() {
        desserts.add(new MenuItem("Piece of Cake", 7.9, "조각케이크 3종 중(택1)"));
        desserts.add(new MenuItem("Egg Tart", 2.9, "손바닥만한 에그타르트"));
        desserts.add(new MenuItem("French Fries", 4.9, "감자튀김"));
        desserts.add(new MenuItem("Strawberry Jam and Scones", 3.2, "딸기잼과 스콘"));
    }

    // 특정 카테고리 메뉴 출력
    public void displayMenu(List<MenuItem> menuList, String category) {
        System.out.println("\n============================== " + category + " 메뉴 ==============================");
        for (int i = 0; i < menuList.size(); i++) {
            menuList.get(i).printMenuItem(i + 1);
        }
        System.out.println("=====================================================================");
    }

    // Getter 메서드
    public List<MenuItem> getBurgers() {
        return burgers;
    }

    public List<MenuItem> getDrinks() {
        return drinks;
    }

    public List<MenuItem> getDesserts() {
        return desserts;
    }
}

Kiosk.java

package com.example.kiosk;

import java.util.Scanner;

// 키오스크의 메인 로직을 관리
public class Kiosk {
    private Scanner scanner;
    private Menu menu;
    private boolean isRunning;

    // 생성자
    public Kiosk() {
        scanner = new Scanner(System.in);
        menu = new Menu();
        isRunning = true;
    }

    // 키오스크 실행
    public void run() {
        while (isRunning) {
            showMainMenu();
            String input = scanner.nextLine().toLowerCase(); // 소문자로 변환

            switch (input) {
                case "1":
                    handleCategorySelection(menu.getBurgers(), "버거");
                    break;
                case "2":
                    handleCategorySelection(menu.getDrinks(), "음료");
                    break;
                case "3":
                    handleCategorySelection(menu.getDesserts(), "디저트");
                    break;
                case "save":
                    addCustomMenuItem();
                    break;
                case "exit":
                    System.out.println("키오스크를 종료합니다.");
                    isRunning = false;
                    break;
                default:
                    System.out.println("올바른 입력이 아닙니다. 다시 시도하세요.");
                    break;
            }
        }
    }

    // 메인 메뉴 출력
    private void showMainMenu() {
        System.out.println("\n=============== Kirby's Burger Kiosk ===============");
        System.out.println("1 : 버거 메뉴 보기");
        System.out.println("2 : 음료 메뉴 보기");
        System.out.println("3 : 디저트 메뉴 보기");
        System.out.println("save : 새 메뉴 추가");
        System.out.println("exit : 종료");
        System.out.println("===================================================");
        System.out.print("선택 : ");
    }

    // 카테고리 메뉴 처리
    private void handleCategorySelection(java.util.List<MenuItem> menuList, String category) {
        while (true) {
            menu.displayMenu(menuList, category);
            System.out.print("메뉴 번호를 선택하세요 (0: 뒤로가기): ");
            int selection;

            try {
                selection = Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("숫자를 입력하세요.");
                continue;
            }

            if (selection == 0) {
                System.out.println("메인 메뉴로 돌아갑니다.");
                return; // 메인 메뉴로 돌아가기
            }

            if (selection >= 1 && selection <= menuList.size()) {
                showMenuDetails(menuList.get(selection - 1)); // 상세 정보 출력
            } else {
                System.out.println("잘못된 번호입니다. 다시 선택하세요.");
            }
        }
    }

    // 메뉴 상세 정보 출력
    private void showMenuDetails(MenuItem item) {
        System.out.println("\n=============== 메뉴 상세 정보 ===============");
        item.printMenuItem(0); // 상세 정보 출력
        System.out.println("0을 입력하여 뒤로 가세요.");
        while (true) {
            System.out.print("선택: ");
            String input = scanner.nextLine();
            if ("0".equals(input)) {
                return; // 카테고리 메뉴로 돌아가기
            } else {
                System.out.println("잘못된 입력입니다. 0을 입력하여 뒤로 가세요.");
            }
        }
    }

    // 사용자 정의 메뉴 추가
    private void addCustomMenuItem() {
        System.out.println("어느 카테고리에 메뉴를 추가하시겠습니까? (1: 버거, 2: 음료, 3: 디저트)");
        String category = scanner.nextLine();
        System.out.print("메뉴 이름: ");
        String name = scanner.nextLine();
        System.out.print("메뉴 가격: ");
        double price = Double.parseDouble(scanner.nextLine());
        System.out.print("메뉴 설명: ");
        String description = scanner.nextLine();

        MenuItem newItem = new MenuItem(name, price, description);

        switch (category) {
            case "1":
                menu.getBurgers().add(newItem);
                break;
            case "2":
                menu.getDrinks().add(newItem);
                break;
            case "3":
                menu.getDesserts().add(newItem);
                break;
            default:
                System.out.println("잘못된 카테고리 선택입니다.");
                return;
        }

        System.out.println("새로운 메뉴가 추가되었습니다!");
    }
}

5️⃣ 단계 '캡슐화 적용하기'

❗ 필수 기능 가이드

  • MenuItem, Menu 그리고 Kiosk 클래스의 필드에 직접 접근하지 못하도록 설정합니다.
  • Getter와 Setter 메서드를 사용해 데이터를 관리합니다.

캡슐화를 5단계 때 따로 진행해야했다니..? 조금 의아하고 이상하게 느껴졌다.
이미 캡슐화를 적용했기에 적용한 부분에 대한 내용을 적어보았다.

private String menuName;
private double menuPrice;
private String menuDescription;

public String getMenuName() {
        return menuName;
    }

    public double getMenuPrice() {
        return menuPrice;
    }

    public String getMenuDescription() {
        return menuDescription;
    }

위의 3가지 속성 모두 private로 선언되어 외부에서 직접적인 접근이 불가능하며 getMenuName, getMenuPrice, getMenuDescription 메서드를 통해서만 데이터를 읽을수 있도록 했다.

private List<MenuItem> burgers;
private List<MenuItem> drinks;
private List<MenuItem> desserts;

burgers , drinks , desserts 속성은 private 으로 선언되어 외부에서 직접 수정할 수 없고 getBurgers , getDrinks , getDesserts 메서드를 통해서만 접근할 수 있도록 했다.

Kiosk 클래스 캡슐화

private Scanner scanner;
private Menu menu;
private boolean isRunning;

scanner , menu , isRunning 필드는 모두 private으로 선언되어 외부에서 접근할 수 없고 키오스크의 실행 상태(isRunning)는 run 메서드 내부에서만 제어되어 외부에서 변경이 불가능하다.


💥도전과제!

이번에는 도전과제를 해보려고 했는데 마감일 하루전에 계속 이렇게 보여서 도전과제를 마감 2시간 전에 볼 수 있었다.. 도전과제를 모두 끝낼 수 있을지 걱정되지만 한 번 시도해려고 한다!


장바구니 기능 추가

우선 Cart 클래스를 따로 생성해서 기능을 분할했다.

private List<MenuItem> cartItems;

    // 생성자
    public Cart() {
        cartItems = new ArrayList<>();
    }

    // 장바구니에 항목 추가
    public void addItem(MenuItem item) {
        cartItems.add(item);
        System.out.println("'" + item.getMenuName() + "'이(가) 장바구니에 추가되었습니다.");
    }

    // 장바구니 항목 출력
    public void displayCart() {
        if (cartItems.isEmpty()) {
            System.out.println("장바구니가 비어 있습니다.");
        } else {
            System.out.println("\n=============== 장바구니 ===============");
            for (int i = 0; i < cartItems.size(); i++) {
                cartItems.get(i).printMenuItem(i + 1);
            }
            System.out.println("========================================");
        }
    }

    // 장바구니 비우기
    public void clearCart() {
        cartItems.clear();
        System.out.println("장바구니가 비워졌습니다.");
    }

    // 장바구니에 있는 항목 수
    public int getItemCount() {
        return cartItems.size();
    }

그 다음에 메뉴 상세 정보 확인 후 장바구니 추가 여부를 확인하도록 처리했다.

// 메뉴 상세 정보 출력
    private void showMenuDetails(MenuItem item) {
        System.out.println("\n============================== 메뉴 상세 정보 ==============================");
        item.printMenuItem(0);
        System.out.println("1: 장바구니에 추가");
        System.out.println("2: 취소 후 뒤로가기");
        System.out.println("=====================================================================");

        while (true) {
            System.out.print("선택: ");
            String input = scanner.nextLine();
            if ("1".equals(input)) {
                cart.addItem(item); // 장바구니에 추가
                return; // 뒤로가기
            } else if ("2".equals(input)) {
                System.out.println("취소되었습니다. 뒤로 돌아갑니다.");
                return; // 뒤로가기
            } else {
                System.out.println("올바른 입력이 아닙니다. 1 또는 2를 입력하세요.");
            }
        }
    }

주문하기 기능 추가

cart 와 마찬가지로 order 라는 클래스를 하나 더 추가해 기능을 분할했다.

private Cart cart; // 장바구니 객체 참조

    // 생성자
    public Order(Cart cart) {
        this.cart = cart;
    }

    // 주문 처리
    public void processOrder() {
        if (cart.getItemCount() == 0) {
            System.out.println("장바구니가 비어 있습니다. 메뉴를 먼저 추가하세요.");
            return;
        }

        // 주문 내역 출력
        System.out.println("\n============================== 주문내역 ==============================");
        // 장바구니 항목만 출력
        cart.printItems();
        // 총 금액 계산
        double totalAmount = cart.calculateTotal();
        System.out.println("총 금액: W " + totalAmount);
        System.out.println("=====================================================================");
        System.out.println("1: 주문하기");
        System.out.println("2: 메뉴판으로 돌아가기");
        System.out.print("선택: ");
    }

    // 주문 완료 메시지
    public void completeOrder() {
        double totalAmount = cart.calculateTotal();
        System.out.println("주문이 완료되었습니다!");
        System.out.println("결제 금액: W " + totalAmount);
        // 주문 후 장바구니 비우기
        cart.clearCart();
    }

그리고 kiosk 클래스에도 추가했다.

// 메인 메뉴 출력
    private void showMainMenu() {
        System.out.println("\n=============== Kirby's Burger Kiosk ===============");
        System.out.println("1 : 버거 메뉴 보기");
        System.out.println("2 : 음료 메뉴 보기");
        System.out.println("3 : 디저트 메뉴 보기");
        System.out.println("cart : 장바구니 보기");
        System.out.println("order : 주문하기");
        System.out.println("exit : 종료");
        System.out.println("===================================================");
        System.out.print("선택 : ");
    }

🛠️ 문제 해결 X 회고

매번 문제 해결에 대해 코멘트를 남겨놓는 것을 종종 잊어버린다. 그래서 도전과제할 때 있었던 문제 해결과 Local history에 남아있는 부분을 보고 적고 있다.

1️⃣ 겹치는 sout은 언제나 당황스럽게 해


시각적으로도 줄이 문제가 있지만.. 줄보다 가장 거슬리는 건 ==== 주문내역 ==== 안에 ==== 장바구니 ==== 가 그대로 출력되는 것이다..

문제는 장바구니에서 참조해 가져오니까 일어나는 당연한(?)일이라 주문출력하는 부분을 분리하기로 했다.

Cart 클래스 수정

// 장바구니 항목 출력 (일반 출력)
    public void displayCart() {
        if (cartItems.isEmpty()) {
            System.out.println("장바구니가 비어 있습니다.");
        } else {
            System.out.println("\n============================== 장바구니 ==============================");
            printItems();
            System.out.println("=====================================================================");
        }
    }

    // 장바구니 항목만 출력
    public void printItems() {
        for (int i = 0; i < cartItems.size(); i++) {
            cartItems.get(i).printMenuItem(i + 1);
        }
    }

Order 클래스 수정

// 주문 내역 출력
        System.out.println("\n=============== 주문 내역 ===============");
        cart.printItems(); // 장바구니 항목만 출력
        double totalAmount = cart.calculateTotal(); // 총 금액 계산
        System.out.println("총 금액: W " + totalAmount);
        System.out.println("========================================");
        System.out.println("1: 주문하기");
        System.out.println("2: 메뉴판으로 돌아가기");
        System.out.print("선택: ");


아주 깔끔하고 만족스럽게 변경되었다.

2️⃣ 언제나 시작점이 고비.. 그 때만 넘기면 괜찮아!

언제나 빈 도화지에 그림을 그려나가는게 어려울 뿐, 조금 그려지기 시작하면 '재미'라는 것이 붙어서 신나게 코딩할 수 있다.

처음 작업한 클래스에는 불필요한 생성자를 호출하는 문제가 있었다.
이건 그냥 봐도 알 정도로 문제가 있었고, 그 부분을 해결하는 과정에서 이해하는 데에만 1시간이 넘게 들었다.

MenuItem도 복잡스럽게 해놓아서 나조차도 수정에 용이하지 못하다는 생각이 들어 40분 동안 단순화를 하는데 고민을 했다. 그 끝에 성공!

3️⃣ 도전과제를 시도해봤지만 2단계까지는 못해서 아쉽다

사실 5주차 강의를 아직 듣지 못했다. 그래서 고급문법을 활용할 짬이 안나는 바람에 도전과제 1레벨까지만 할 수 있었다. 오늘부터 스프링 강의가 지급된다고 들었는데 그 전에 고급문법을 활용해볼 수 있도록 개인적으로 과제를 만들어봐야겠다는 생각이 들었다.

작업 후기

소요시간 : 약 2일 (Local History 기준 시간으로는 14시간)
난이도 : 중 - 상


>> Java : Kiosk 만들기 GitHub Code 바로가기
다 만들어진 코드는 위의 깃허브에 올려놓았다.

profile
전공은 컴퓨터공학, 복수전공은 해킹보안학, 직장은 방학(파워 구직중)

0개의 댓글