개발 낙서장

JAVA 개인 과제 - 키오스크 만들기 - 1일차 본문

Java/Sparta

JAVA 개인 과제 - 키오스크 만들기 - 1일차

권승준 2024. 1. 5. 20:59

과제 소개

📢 내가 좋아하는 카페 또는 패스트푸드점의 키오스크를 만들어보자!

  • 지금까지 배워온 Java 언어를 사용하여 키오스크 프로그램을 만들기.
  • 내가 좋아하는 카페나 패스트푸드점의 메뉴판 데이터를 사용하기.
1. 메뉴판을 보고 주문할 수 있는 Java 프로그램
2. 화면은 System.out.println() 메소드를 사용해서 심플하게 출력
3. 메뉴 클래스와 주문 클래스를 사용하여 Java 의 핵심 기능인 상속을 최대한 사용
4. 메뉴를 최대한 다양하게 구성

필수 요구사항

  • 메뉴 클래스 : 이름, 설명 필드를 가지는 클래스
  • 상품 클래스 : 이름, 가격, 설명 필드를 가지는 클래스(메뉴 클래스를 상속)
  • 주문 클래스 : 상품 객체를 담는 클래스
  1. 메인 메뉴판 화면
    • 메인 메뉴판이 출력되며 메뉴판에는 상품 메뉴가 출력된다.
    • 상품 메뉴는 간단한 설명과 함께 출력 되며 최소 3개 이상 출력된다.
    • 상품 메뉴 아래에는 Order(주문)와 Cancel(주문 취소) 옵션이 출력된다.
  2. 상품 메뉴판 화면
    • 상품 메뉴 선택 시 해당 카테고리의 메뉴판이 출력됩니다.
    • 메뉴판에는 각 메뉴의 이름과 가격과 간단한 설명이 표시됩니다.
  3. 구매 화면
    • 상품 선택 시 해당 상품을 장바구니에 추가할지 확인하는 문구가 출력 됩니다.
    • 1.확인 입력 시 장바구니에 추가되었다는 안내 문구와 함께 메인 메뉴로 다시 출력 됩니다.\
  4. 주문 화면
    • 5.Order 입력 시 장바구니 목록을 출력해줍니다.
    • 장바구니에서는 추가된 메뉴들과 총 가격의 합을 출력해줍니다.
    • 1.주문 입력 시 주문완료 화면으로 넘어가고, 2.메뉴판 입력 시 다시 메인 메뉴로 돌아옵니다.
  5. 주문완료 화면
    • 1.주문 입력 시 대기번호를 발급해줍니다.
    • 장바구니는 초기화되고 3초 후에 메인 메뉴판으로 돌아갑니다.
  6. 주문 취소 화면
    • 메뉴판에서 6.Cancel 입력시 주문을 취소할지 확인을 요청하는 문구가 출력 됩니다.
    • 1.확인 을 입력하면 장바구니는 초기화되고 취소 완료 문구와 함께 메뉴판이 출력 됩니다.
  7. 선택 요구사항
    • 주문 개수 기능
    • 상품 옵션 기능
    • 총 판매금액 조회 기능
    • 총 판매상품 목록 조회 기능

설계

  • 전체 메뉴 클래스
    • 이름
    • 상세 메뉴 리스트
  • 상세 메뉴 클래스(extends 메뉴 클래스)
    • 이름
    • 설명
    • 상품 리스트
  • 상품 클래스(extends 메뉴 클래스)
    • 상품 이름
    • 상품 가격
    • 상품 설명
  • 주문 클래스
    • 장바구니(List 혹은 Map - HashMap)

구현

  • 최상위 메뉴 클래스
    • 모든 메뉴, 상품 클래스는 해당 클래스를 상속한다.
    • 이름, 설명은 공통으로 포함되며 각 클래스 별로 필요한 추가 변수나 함수를 구현할 수 있다.
더보기
package Menu;

public class Menu {
    String name;
    String desc;

    public Menu(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}
  • TopMenu 클래스
    • 메인 메뉴인지, 추가 메뉴인지, 기타 작업인지를 구분하는 클래스이다.
    • 각 항목마다 하위 클래스들이 존재하기 때문에(ex. 메인 메뉴 안에는 돈까스, 우동, 소바 등의 분류가 있다.)
      List 형식의 ChildMenuList를 관리한다.
더보기
package Menu;
import java.util.ArrayList;
import java.util.List;

public class TopMenu extends Menu {
    List<DetailMenu> childMenuList;

    public TopMenu(String name, String desc) {
        super(name, desc);
        childMenuList = new ArrayList<>();
    }

    public List<DetailMenu> getChildMenuList() {
        return childMenuList;
    }

    public void setChildMenuList(List<DetailMenu> childMenuList) {
        this.childMenuList = childMenuList;
    }

    public void addChildMenu(DetailMenu childMenu) {
        childMenuList.add(childMenu);
    }

    public void removeChildMenu(DetailMenu childMenu) {
        childMenuList.remove(childMenu);
    }
}
  • DetailMenu 클래스
    • TopMenu에서 관리하는 ChildMenu로 음식의 종류, 작업의 종류가 여기에 속한다.
    • 해당 클래스 또한 상품들을 갖고 있어야 하기 때문에 List 형식의 ProductList가 존재한다.
더보기
package Menu;
import Product.Product;

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

public class DetailMenu extends Menu {
    List<Product> productList;

    public DetailMenu(String name, String desc) {
        super(name, desc);
        productList = new ArrayList<>();
    }

    public List<Product> getProductList() {
        return productList;
    }

    public void setProductList(List<Product> productList) {
        this.productList = productList;
    }

    public void addProduct(Product product) {
        productList.add(product);
    }

    public void removeProduct(Product product) {
        productList.remove(product);
    }
}
  • Product 클래스
    • 각 상품의 세부 내용을 담는 클래스이다.
더보기
package Product;

import Menu.Menu;

public class Product extends Menu {
    double price;

    public Product(String name, String desc, double price) {
        super(name, desc);
        this.price = price;
    }

    public Double getPrice() {
        return price;
    }
}
  • RestaurantData 클래스
    • 각 메뉴들, 상품들의 데이터를 관리하는 클래스이다. DB의 역할을 한다.
더보기
package Data;

import Menu.DetailMenu;
import Menu.TopMenu;
import Product.Product;

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

public class RestaurantData {
    public static String restaurantName = "스파르타 돈까스";
    public static List<TopMenu> topMenuList = new ArrayList<>();

    TopMenu mainMenu = new TopMenu("메인 메뉴", "");
    TopMenu addMenu = new TopMenu("추가 메뉴", "");

    DetailMenu porkCutlet = new DetailMenu("돈까스", "바삭바삭한 돈까스");

	//...

    Product mushroomPorkCurry = new Product("머쉬룸포크카레", "버섯향이 느껴지는 부드럽고 진한 카레", 9500);
    Product shrimpTempuraCurry = new Product("에비텐카레", "새우튀김이 들어간 부드럽고 진한 카레", 11500);

    public void Init() {
        mainMenu.addChildMenu(porkCutlet);
        mainMenu.addChildMenu(soba);
        mainMenu.addChildMenu(udon);
        mainMenu.addChildMenu(curry);

        addMenu.addChildMenu(miniCurry);

		//...

        udon.addProduct(shrimpTempuraUdon);

        curry.addProduct(mushroomPorkCurry);
        curry.addProduct(shrimpTempuraCurry);
    }
}
  • Main 클래스
    • 실제로 키오스크가 동작하는 클래스이다.
    • 일단 임시로 Main 클래스에 다 넣었지만 추후에 별도로 키오스크 클래스를 만들 것이다.
    • 입력을 받고 입력에 맞게 데이터를 가져와 출력해주는 기능을 한다.
더보기
import Data.RestaurantData;
import Menu.DetailMenu;
import Menu.TopMenu;
import Menu.Menu;
import Product.Product;

import java.util.*;

import static Data.RestaurantData.restaurantName;
import static Data.RestaurantData.topMenuList;

public class Main {
    static Map<Integer, Menu> controlKiosk = new HashMap<>();
    static RestaurantData rd;
    static Scanner sc;

    public static void main(String[] args) {
        sc = new Scanner(System.in);

        rd = new RestaurantData();
        rd.Init();

        ShowMain();
    }

    static void ShowMain() {
        System.out.println("\"" + restaurantName + "에 오신걸 환영합니다.\"");
        System.out.println("아래 메뉴판을 보시고 메뉴를 골라 입력해주세요.");

        int index = 1;
        controlKiosk.clear();

        for(TopMenu topMenu : topMenuList) {
            System.out.println("\n[ " + topMenu.getName() + " ]");
            for(DetailMenu detailMenu : topMenu.getChildMenuList()) {
                System.out.printf("%d. %-30s | %-50s\n", index, detailMenu.getName(), detailMenu.getDesc());
                controlKiosk.put(index, detailMenu);
                index++;
            }
        }

        String input = sc.nextLine();
        ShowDetail(Integer.parseInt(input));
    }

    static void ShowDetail(int input) {
        System.out.println("\n\"" + restaurantName + "에 오신걸 환영합니다.\"");
        System.out.println("아래 메뉴판을 보시고 상품를 골라 입력해주세요.");

        DetailMenu detailMenu = (DetailMenu)controlKiosk.get(input);

        System.out.println("[ " + detailMenu.getName() + " ]");

        int index = 1;
        controlKiosk.clear();

        for(Product p : detailMenu.getProductList()) {
            System.out.printf("%d. %-30s | %-10s | %-50s\n", index, p.getName(), p.getPrice().toString(), p.getDesc());
            controlKiosk.put(index, p);
            index++;
        }

        String answer = sc.nextLine();

        ShowAddCard(Integer.parseInt(answer));
    }

    static void ShowAddCard(int input) {
        Product product = (Product)controlKiosk.get(input);

        System.out.printf("\n[ %-30s | %-10s | %-50s ]\n", product.getName(), product.getPrice().toString(), product.getDesc());
        System.out.println("위 메뉴를 장바구니에 추가하시겠습니까?");
        System.out.println("1. 확인\t2. 취소");

        String answer = sc.nextLine();

        if(answer.equals("1")) {
            System.out.println(product.getName() + "(이)가 장바구니에 추가되었습니다.");
        }

        controlKiosk.clear();

        ShowMain();
    }
}

 

문제점

이렇게 구현을 진행하다 장바구니를 구현하려다 보니까 막혔다.

TopMenu 클래스인 OrderMenu 안에는 DetailMenu 클래스인 Order과 Cancel이 있다.
각각 장바구니에 있는 주문을 완료하는 기능, 주문을 취소하는 기능을 해야 한다.

Order과 Cancel을 DetailMenu 클래스로 생성해버리면 조건문과 출력문이 조금 복잡해지고 어떤 에러나 예외가 발생할지 모르기 때문에 따로 클래스를 만들어주기로 했다.
클래스의 구분은 자바의 Object에 있는 메소드인 getSimpleName()를 사용해 이름이 DetailMenu인지, OrderMenu인지, CancelMenu인지를 구분해 각각의 작업을 하도록 했다.

또한 클래스는 단일 책임 원칙을 지켜야 하므로 Main에 있던 전체 실행문을 KioskApp이라는 클래스를 만들어 옮겨주었다.
KioskApp에서는 오로지 키오스크 화면을 출력해주고 출력을 위한 데이터를 갱신해주는 역할만 한다.

정리해 보면 각 클래스는 각각의 기능을 한다.

  • TopMenu : 가장 부모의 메뉴 클래스. DetailMenu의 List를 갖고 있으며 해당 List의 getter 함수, add 함수가 있다.
  • DetailMenu : 상세 메뉴 클래스. 상품 목록을 갖고 있으며 상품 목록의 getter 함수, add 함수가 있다.
  • Product : 상품 클래스. 가격의 getter 함수가 있다.
  • OrderMenu : 주문 클래스. 아직 별도의 기능은 없지만 키오스크 조작을 구분하기 위해 만든 클래스이다.
  • CancelMenu : 취소 클래스. 위와 동일하다.
  • RestaurantData : 주문들의 데이터를 담고 있는 클래스. DB와 유사한 역할을 한다.
  • CartData : 장바구니 클래스. Map<Product, Integer> 형식의 변수를 선언해 상품을 몇개 주문했는지 알 수 있게 했다. 장바구니에 상품을 추가하고 장바구니를 가져오고 비우는 기능이 있다.
  • KioskApp : 키오스크의 모든 조작을 다루는 클래스이다. 모든 출력은 해당 클래스에서 이루어지며 입력에 따른 메뉴들의 데이터를 갖고오고 주문이나 취소 조작을 하며 장바구니를 채우거나 비우는 기능을 한다.

결과 화면

 


 

Comments