키오스크 프로젝트 Lv4, Lv5

서연·2025년 5월 1일

Java

목록 보기
27/36

✅ 객체 지향 설계를 적용해 음식 메뉴와 주문 내역을 클래스 기반으로 관리하고 캡슐화 적용

⚙️ 구조

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

📄 코드

Lv4Main.java

package Lv4;

public class Lv4Main {
    public static void main(String[] args) {
        Lv4Menu lv4Menu = new Lv4Menu();

        lv4Menu.getLv4Menus().add(new Lv4Menu("Burgers"));
        lv4Menu.getLv4Menus().add(new Lv4Menu("Drinks"));
        lv4Menu.getLv4Menus().add(new Lv4Menu("Desserts"));

        // Lv4Menu 에 있는 burgersMenu 라는 리스트에 getter 를 사용해 햄버거 정보를 추가
        lv4Menu.getBurgersMenu().add(new Lv4MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거"));
        lv4Menu.getBurgersMenu().add(new Lv4MenuItem("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"));
        lv4Menu.getBurgersMenu().add(new Lv4MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"));
        lv4Menu.getBurgersMenu().add(new Lv4MenuItem("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거"));

        // Lv4Menu 에 있는 drinksMenu 라는 리스트에 getter 를 사용해 음료 정보를 추가
        lv4Menu.getDrinksMenu().add(new Lv4MenuItem("Fountain Soda", 2.9, "코카콜라, 코카콜라 제로, 스프라이트, 환타 오렌지"));
        lv4Menu.getDrinksMenu().add(new Lv4MenuItem("Lemonade", 4.5, "매장에서 직접 만드는 상큼한 레몬에이드"));
        lv4Menu.getDrinksMenu().add(new Lv4MenuItem("Fresh Brewed Iced Tea", 3.7, "직접 유기농 홍차를 우려낸 아이스 티"));
        lv4Menu.getDrinksMenu().add(new Lv4MenuItem("Fifty/Fifty", 4.0, "레몬에이드와 유기농 홍차를 우려낸 아이스 티가 만나 탄생한 시그니처 음료"));

        // Lv4Menu 에 있는 dessertsMenu 라는 리스트에 getter 를 사용해 디저트 정보를 추가
        lv4Menu.getDessertsMenu().add(new Lv4MenuItem("Shack Attack", 6.2, "진한 초콜릿 커스터드에 퍼지 소스와 세 가지 초콜릿 토핑이 블렌딩된 콘크리트"));
        lv4Menu.getDessertsMenu().add(new Lv4MenuItem("Classic Hand-Spun Shakes", 6.8, "쫀득하고 진한 커스터드가 들어간 클래식 쉐이크"));
        lv4Menu.getDessertsMenu().add(new Lv4MenuItem("Cup & Cones", 5.7, "신선하게 제조하는 쫀득하고 진한 아이스크림"));

        Lv4Kiosk lv4Kiosk = new Lv4Kiosk(lv4Menu);
        lv4Kiosk.start(); // Lv4Kiosk 에 있는 start 함수 실행

    }
}

Lv4MenuItem.java

package Lv4;

public class Lv4MenuItem {
    // 1. 속성
    private String name;
    private double price;
    private String foodDetails;

    // 2. 생성자
    public Lv4MenuItem(String name, double price, String foodDetails) {
        this.name = name;
        this.price = price;
        this.foodDetails = foodDetails;

    }

    // 3. 기능
    // 주소값을 출력하는 것이 아닌 리스트안에 들어있는 값을 출력하기 위해 toString 메서드 작성
    public String toString() {
        return name + " | " + "W" + price + " | " + foodDetails;
    }
}

Lv4Kiosk.java

package Lv4;

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

public class Lv4Kiosk {
    Lv4Menu lv4Menu;
    Scanner scanner = new Scanner(System.in);

    // 2. 생성자
    public Lv4Kiosk(Lv4Menu lv4Menu) {
        this.lv4Menu = lv4Menu;
    }

    // 3. 기능(메서드)
    public void start() { // 입력과 반복문 로직
        while (true) { // 사용자가 종료를 누르기 전까지 계속 반복
            int num1 = 0;
            int num2 = 0;
            System.out.println("\n");
            lv4Menu.mainMenu();
            while (true) {
                System.out.print("\n");
                System.out.print("원하시는 메뉴를 선택해주세요: ");
                try {
                    num1 = scanner.nextInt();
                    if (num1 < 0 || num1 > 3) {
                        throw new IllegalArgumentException();
                    }
                    break;
                } catch (IllegalArgumentException | InputMismatchException e) {
                    System.out.println("올바른 숫자를 입력해주세요.");
                    scanner.nextLine();
                }
            }
            if (num1 == 0) {
                System.out.println("프로그램을 종료합니다.");
                break; //종료
            }

            while (true) {
                System.out.println("\n");
                if (num1 == 1) {
                    lv4Menu.burgersMenu();
                } else if (num1 == 2) {
                    lv4Menu.drinkMenu();
                } else if (num1 == 3) {
                    lv4Menu.dessertsMenu();
                }
                try { // 다른 값을 입력했을 시 예외처리
                    System.out.print("원하시는 메뉴를 선택해주세요: ");
                    num2 = scanner.nextInt();
                    if (num2 == 0) break; // 0을 입력하면 메인메뉴로 돌아가게 된다.
                    if (num1 == 1) {
                        System.out.println("선택한 메뉴: " + lv4Menu.getBurgersMenu().get(num2 - 1));
                    } else if (num1 == 2) {
                        System.out.println("선택한 메뉴: " + lv4Menu.getDrinksMenu().get(num2 - 1));
                    } else if (num1 == 3) {
                        System.out.println("선택한 메뉴: " + lv4Menu.getDessertsMenu().get(num2 - 1));
                    }
                } catch (IndexOutOfBoundsException | InputMismatchException e) {
                    System.out.println("올바른 숫자를 입력해주세요");
                    scanner.nextLine(); // 버퍼에 남아있는 값을 제거하기 위해 사용
                }
            }
        }
    }
}

Lv4Menu.java

package Lv4;

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

public class Lv4Menu {// MenuItem 클래스를 관리하는 클래스
    // 1. 속성
    private final List<Lv4MenuItem> burgersMenu = new ArrayList<>();
    private final List<Lv4MenuItem> drinksMenu = new ArrayList<>();
    private final List<Lv4MenuItem> dessertsMenu = new ArrayList<>();
    private final List<Lv4Menu> lv4Menus = new ArrayList<>();
    private String name;

    // 2. 생성자
    public Lv4Menu() {
    }

    public Lv4Menu(String name) {
        this.name = name;
    }

    // 3. 기능(메서드)
    public void burgersMenu() {
        System.out.println("[ BURGERS MENU ]");
        for (int i = 0; i < burgersMenu.size(); i++) {
            System.out.print(i + 1 + ". ");
            System.out.println(burgersMenu.get(i));
        }
        System.out.println("0. 뒤로가기");
    }

    public void mainMenu() {
        System.out.println("[ MAIN MENU ]");
        for (int i = 0; i < lv4Menus.size(); i++) {
            System.out.print(i + 1 + ". ");
            System.out.println(lv4Menus.get(i));
        }
        System.out.println("0. 종료");
    }

    public void drinkMenu() {
        System.out.println("[ DRINKS MENU ]");
        for (int i = 0; i < drinksMenu.size(); i++) {
            System.out.print(i + 1 + ". ");
            System.out.println(drinksMenu.get(i));
        }
        System.out.println("0. 뒤로가기");
    }

    public void dessertsMenu() {
        System.out.println("[ DESSERTS MENU ]");
        for (int i = 0; i < dessertsMenu.size(); i++) {
            System.out.print(i + 1 + ". ");
            System.out.println(dessertsMenu.get(i));
        }
        System.out.println("0. 뒤로가기");
    }

    public String toString() {
        return name;
    }

    public List<Lv4MenuItem> getBurgersMenu() {
        return burgersMenu;
    }

    public List<Lv4MenuItem> getDrinksMenu() {
        return drinksMenu;
    }

    public List<Lv4MenuItem> getDessertsMenu() {
        return dessertsMenu;
    }

    public List<Lv4Menu> getLv4Menus() {
        return lv4Menus;
    }
}

⚠️ 트러블 슈팅 ⚠️

문제 상황

Lv4Main 클래스에서 Lv4Kiost객체화를 시켜 Lv4Kioststart() 함수를 실행 시켰을 때 Main 에서 리스트에 넣은 값이 출력되지 않는 상황

문제 이유

객체를 생성할 때 Lv4Kiosk lv4Kiosk = new Lv4Kiosk();처럼 기본 생성자를 사용한 경우 start() 함수에서 menuItems를 출력하려고 해도 값이 없어서 아무것도 출력되지 않은 것이다.

해결 방법

Lv4Kiosk lv4Kiosk = new Lv4Kiosk(lv4Menu);를 사용해서 menuItems를 올바르게 초기화화 하면 start() 함수에서 List의 값을 정상적으로 출력할 수 있게 되었다.

💡 느낀점

기본 생성자매개변수 생성자의 차이를 확실히 이해하였고 객체가 제대로 초기화되지 않으면 예상한 대로 동작하지 않는다는 점 배우게 되었다. 문제 해결을 위해 생성자 사용법을 잘못 적용했을 때 발생할 수 있는 오류를 경험하며 객체 지향 프로그래밍에서 초기화와 값을 전달하는 과정이 얼마나 중요한지 깨달았다. 게터(getter)를 사용하면서 객체의 상태를 안전하게 가져오는 방법을 배우고 직접 값을 수정하는 대신 안전하게 접근하는 방법을 익히게 되었다.

🔗 GitHub

프로젝트 코드 보러 가기

0개의 댓글