- 23.10.20) TIL - 개인프로젝트(키오스크)2023년 10월 20일 20시 51분 44초에 업로드 된 글입니다.작성자: oneseel
오늘 한 일
- 개인 프로젝트 거의 완료
어제에 이어 오늘도 개인프로젝트를 만들었다.
옵션 기능과 총 판매금액 조회 기능, 총 판매상품 목록 조회 기능을 추가했다.
(사실상 최종, 전체 코드 작성)
<Menu class>
public class Menu { private String menuName; // 메뉴 이름 private String menuDescription; // 메뉴 설명 // 생성자 public Menu (String menuName, String menuDescription) { this.menuName = menuName; this.menuDescription = menuDescription; } // 메서드 // 메뉴 이름을 반환하는 메서드 public String getMenuName() { return menuName; } // 메뉴 설명을 반환하는 메서드 public String getMenuDescription() { return menuDescription; } }
<MenuItems class>
- MenuItems는 Menu를 상속받은 클래스이다.
- 메뉴이름과 메뉴설명을 반환하는 메서더는 오버라이딩했고, 상품의 가격과 수량을 반환하는 메서드를 가진다.
- 장바구니에 있는 메뉴의 수량이 증가하는 것을 반환하는 메서드를 가진다.
- 옵션 맵에 옵션을 추가하는 메서드와 그 옵션맵을 반환하는 메서드를 가진다.
- 판매된 상품 수량을 반환하는 메서드와 판매된 상품의 수량이 증가하는 메서드를 가진다.
import java.util.HashMap; import java.util.Map; public class MenuItems extends Menu { private int menuItemPrice; // 상품 가격 private int menuItemCount; // 상품 개수 private Map<Integer, Option> optionMap; // 옵션 맵 private int soldCount; // 판매된 상품 개수 public MenuItems(String menuName, String menuDescription, int menuItemPrice, int menuItemCount) { super(menuName, menuDescription); this.menuItemPrice = menuItemPrice; this.menuItemCount = menuItemCount; this.optionMap = new HashMap<>(); this.soldCount = 0; } // 메서드 @Override public String getMenuName() { return super.getMenuName(); } @Override public String getMenuDescription() { return super.getMenuDescription(); } // 메뉴 상품의 가격을 반환하는 메서드 public int getMenuItemsPrice() { return menuItemPrice; } // 메뉴 상품의 수량을 반환하는 메서드 public int getMenuItemCount() { return menuItemCount; } // 메뉴 상품의 수량이 증가하는 메서드 public void increaseItemCount() { menuItemCount++; } // 옵션 맵에 옵션을 추가하는 메서드 public void addOption(int optionNumber, Option option) { optionMap.put(optionNumber, option); } // 옵션 맵을 반환하는 메서드 public Map<Integer, Option> getOptionMap() { return optionMap; } // 판매된 상품 수량을 반환하는 메서드 public int getSoldCount() { return soldCount; } // 판매된 상품 수량을 증가하는 메서드 public void increaseSoldCount() { soldCount++; } }
<Order class>
- Order class는 장바구니 목록을 저장하는 ArrayList와 총 판매금액을 저장하는 변수와 판매된 상품을 저장하는 ArrayList를 가진다.
- 장바구니 물품을 추가하는 메서드에 총 판매금액을 업데이트하는 부분과 판매된 상품 목록을 업데이트 하는 부분을 추가하였다.
- 총 판매금액은 장바구니에 있는 물품의 가격의 수량을 계산하고 totalSales에 계속 값을 더해줘서 총 판매금액이 나온다.
- 판매 목록의 경우는 장바구니에 있는 물품들을 ArrayList에 계속 추가해준다.
import java.util.ArrayList; public class Order { private ArrayList<MenuItems> cart = new ArrayList<>(); // 장바구니 목록 private int totalSales = 0; // 총 판매금액 private ArrayList<MenuItems> soldItems = new ArrayList<>(); // 판매된 상품 목록 // 메서드 // 장바구니에 물품을 추가하는 메서드 public void addToCart(MenuItems menuItems) { if (menuItems != null) { boolean isAlreadyInCart = false; for (MenuItems item : cart) { // 장바구니에 이미 같은 메뉴가 있는지 확인 if (item.getMenuName().equals(menuItems.getMenuName())) { item.increaseItemCount(); // 이미 장바구니에 있는 경우 수량 증가 isAlreadyInCart = true; item.increaseSoldCount(); // 판매된 숫자 증가 break; } } if (!isAlreadyInCart) { cart.add(menuItems); // 장바구니에 물품 추가 menuItems.increaseSoldCount(); // 판매된 숫자 증가 } // 총 판매금액 업데이트 totalSales += menuItems.getMenuItemCount() * menuItems.getMenuItemsPrice(); // 판매된 상품 목록 업데이트 soldItems.add(menuItems); } else { System.out.println("선택한 메뉴가 없습니다. 다시 시도해주세요."); } } // 장바구니에 있는 물품을 전부 제거하는 메서드 public void clearOrder() { cart.clear(); } // 장바구니에 있는 물품을 확인하는 메서드 public void getOrder() { if (cart.isEmpty()) { System.out.println("장바구니가 비어 있습니다."); } else { for (MenuItems item : cart) { System.out.println(item.getMenuName() + " \t|\t " + item.getMenuItemCount() + "개 \t|\t " + item.getMenuItemsPrice() + "원 \t|\t " + item.getMenuDescription()); } } } // 장바구니에 있는 물품의 가격을 합산하는 메서드 public int totalOrder() { int sum = 0; for (MenuItems item : cart) { sum += item.getMenuItemCount() * item.getMenuItemsPrice(); } return sum; } // 총 판매금액을 조회하는 메서드 public int getTotalSales() { return totalSales; } // 판매된 상품 목록을 조회하는 메서드 public ArrayList<MenuItems> getSoldItems() { return soldItems; } }
<Option class>
- 옵션이름과 옵션가격의 변수를 갖는다.
- 각각 이름과 가격을 반환하는 메서드를 가진다.
public class Option { private String optionName; // 옵션 이름 private int optionPrice; // 옵션 가격 public Option(String optionName, int optionPrice) { this.optionName = optionName; this.optionPrice = optionPrice; } public int getOptionPrice() { return optionPrice; } public String getOptionName() { return optionName; } }
<Main class 1>
- 메뉴맵과 각각 메뉴들의 상품으로 이루어진 맵(chickenMap 등)과 상품으로 이루어진 맵으로 구성된 맵(menuItemsMap)의 객체를 생성하고 그 객체에 값을 넣어준다.
- 각 상품의 옵션맵을 추가해서 옵션기능을 추가한다
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); Order order = new Order(); Map<Integer, Menu> menuMap = new HashMap<>(); Map<Integer, Map<Integer, MenuItems>> menuItemsMap = new HashMap<>(); Map<Integer, MenuItems> chickenMap = new HashMap<>(); Map<Integer, MenuItems> burgerMap = new HashMap<>(); Map<Integer, MenuItems> sideMap = new HashMap<>(); Map<Integer, MenuItems> drinkMap = new HashMap<>(); int waitingNumber = 0; // 대기 번호 // 메뉴맵 menuMap.put(1, new Menu("Chicken", "치킨입니다.")); menuMap.put(2, new Menu("Hamburger", "햄버거입니다.")); menuMap.put(3, new Menu("Side", "사이드입니다.")); menuMap.put(4, new Menu("Drink", "음료입니다.")); // 상품맵 menuItemsMap.put(1, chickenMap); menuItemsMap.put(2, burgerMap); menuItemsMap.put(3, sideMap); menuItemsMap.put(4, drinkMap); // 치킨맵 chickenMap.put(1, new MenuItems("갓양념블랙라벨", "KFC에서도 ‘양념 순살’을 먹고 싶다는 고객님들을 위해 준비했다! 블랙라벨 치킨의 변신! 닭다리 통살 블랙라벨이 갓양념과 만났다!", 3400, 1)); chickenMap.put(2, new MenuItems("갓양념치킨", "달콤 매콤, 먹을수록 땡기는 맵달의 조화 한국인 입맛에 딱 맞춘 환상의 양념치킨", 3300, 1)); chickenMap.put(3, new MenuItems("켄터키통다리순살치킨", "부드러운 닭다리 통살로 만든 최고급 프리미엄 치킨", 3100, 1)); chickenMap.put(4, new MenuItems("오리지널치킨", "KFC만의 11가지 비밀양념, 고압쿠킹 방식으로 육즙이 살아있어 촉촉 담백한 오리지널치킨", 3000, 1)); chickenMap.put(5, new MenuItems("핫크리스피치킨", "KFC만의 비법으로 매콤 바삭하게 튀겨낸 KFC 핫크리스피치킨", 3000, 1)); // 버거맵 ... // 사이드맵 ... // 음료맵 ... // 옵션맵(치킨) MenuItems chickenItem1 = chickenMap.get(1); chickenItem1.addOption(1, new Option("갓양념블랙라벨(1조각)", 3400)); chickenItem1.addOption(2, new Option("갓양념블랙라벨(3조각)", 9900)); chickenItem1.addOption(3, new Option("갓양념블랙라벨(5조각)", 16200)); chickenItem1.addOption(4, new Option("갓양념블랙라벨(8조각)", 25200)); ... // 옵션맵(버거) ... // 옵션맵(사이드) ... // 옵션맵(음료) ...
<Main class 2>
- 기존 코드에 case들에 중복된 코드들을 하나의 메서드로 정리했다.(인텔리제이의 기능을 이용)
- 총 판매금액과 총 판매 상품을 조회하는 기능을 추가했다. Order class에 있는 메서드를 활용해서 출력하게 했다.
while (true) { // <메인 메뉴> System.out.println("KFC에 오신걸 환영합니다."); System.out.println("아래 메뉴판을 보시고 메뉴를 골라 입력해주세요."); System.out.println(); System.out.println("[KFC MENU]"); for (int i = 1; i <= menuMap.size(); i++) { Menu menu = menuMap.get(i); System.out.println(i + ". " + menu.getMenuName() + " \t|\t " + menu.getMenuDescription()); } System.out.println(); System.out.println("[ORDER MENU]"); System.out.println("5. Order \t|\t 장바구니를 확인 후 주문합니다."); System.out.println("6. Cancel \t|\t 진행중인 주문을 취소합니다."); System.out.println(); int choice = sc.nextInt(); System.out.println(); switch (choice) { // <1번 치킨 상품> case 1: int chickenChoice = menuItems("[CHICKEN MENU]", chickenMap, sc); menuItemsChoiceMethod(sc, chickenMap, chickenChoice, order); break; // <2번 버거 상품> case 2: int burgerChoice = menuItems("[HAMBURGER MENU]", burgerMap, sc); menuItemsChoiceMethod(sc, burgerMap, burgerChoice, order); break; // <3번 사이드 상품> case 3: int sideChoice = menuItems("[SIDE MENU]", sideMap, sc); menuItemsChoiceMethod(sc, sideMap, sideChoice, order); break; // <4번 음료 상품> case 4: int drinkChoice = menuItems("[DRINK MENU]", drinkMap, sc); menuItemsChoiceMethod(sc, drinkMap, drinkChoice, order); break; // <5번 주문하기> case 5: System.out.println("아래와 같이 주문 하시겠습니까?"); System.out.println(); System.out.println("[Order Menu]"); order.getOrder(); System.out.println(); System.out.println("[Total]"); int totalPrice = order.totalOrder(); System.out.println(totalPrice); System.out.println(); System.out.println("1. 주문 \t\t 2. 메뉴판"); int orderMenuChoice = sc.nextInt(); switch (orderMenuChoice) { case 1: System.out.println(); System.out.println("주문이 완료되었습니다!"); System.out.println(); waitingNumber++; System.out.println("대기번호는 [ " + waitingNumber + " ] 번 입니다."); System.out.println("(3초후 메뉴판으로 돌아갑니다.)"); System.out.println(); order.clearOrder(); try { Thread.sleep(3000); // 3초 대기 } catch (InterruptedException e) { e.printStackTrace(); } break; case 2: System.out.println("메뉴판으로 돌아갑니다."); System.out.println(); break; default: System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } break; // <6번 취소하기> case 6: System.out.println("진행하던 주문을 취소하시겠습니까?"); System.out.println("1. 확인 \t\t 2. 취소"); int cancelChoice = sc.nextInt(); System.out.println(); switch (cancelChoice) { case 1: order.clearOrder(); System.out.println("진행하던 주문이 취소되었습니다."); System.out.println(); break; case 2: System.out.println("메뉴판으로 돌아갑니다."); System.out.println(); break; default: System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } break; // <0번 총 판매금액 조회> case 0: ArrayList<MenuItems> soldItems = order.getSoldItems(); if (soldItems.isEmpty()) { System.out.println("아직 판매된 상품이 없습니다."); } else { System.out.println("총 판매 상품 목록:"); for (MenuItems item : soldItems) { System.out.println(item.getMenuName() + " \t|\t " + item.getMenuItemsPrice() + "원 \t|\t " + item.getSoldCount()); } } System.out.println(); int sales = order.getTotalSales(); System.out.println("현재까지 총 판매된 금액은 " + sales + "원 입니다."); System.out.println(); System.out.println("1. 돌아가기"); break; default: System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } } }
1) 상품메뉴판 메서드 : 기존코드에서 중복되던 부분을 합친 메서드
// 상품메뉴판 메서드 private static int menuItems(String x, Map<Integer, MenuItems> menuItemsMap, Scanner sc) { System.out.println("KFC에 오신걸 환영합니다."); System.out.println("아래 상품메뉴판을 보시고 메뉴를 골라 입력해주세요."); System.out.println(); System.out.println(x); for (int i = 1; i <= menuItemsMap.size(); i++) { MenuItems item = menuItemsMap.get(i); System.out.println(i + ". " + item.getMenuName() + " \t|\t " + item.getMenuItemsPrice() + "원" + " \t|\t " + item.getMenuDescription()); } int menuItemsChoice = sc.nextInt(); System.out.println(); return menuItemsChoice; }
2) 장바구니 추가 메서드와 확인 메서드
- 선택된 물품이 1보다 크거나 같고 주어진 맵의 사이즈보다 작거나 같을 때, MenuItmes로 이루어진 선택된 상품을 출력한다.
- 옵션이 있다면 반복문을 통해 선택된 상품의 옵션맵의 밸류를 옵션 객체에 넣어주고, 그 옵션이름과 그 가격을 출력한다.
- 선택된 옵션이 1보다 크거나 같고 주어진 맵의 사이즈보다 작거나 같을 때, 선택된 옵션을 가져오고 그걸 newItem 객체에 넣어서 장바구니에 추가한다.
- 옵션이 없는 경우 그냥 추가한다.
// 장바구니 추가 메서드 public static void menuItemsChoiceMethod(Scanner sc, Map<Integer, MenuItems> menuItemsMap, int menuItemsChoice, Order order) { if (menuItemsChoice >= 1 && menuItemsChoice <= menuItemsMap.size()) { MenuItems selectedMenuItem = menuItemsMap.get(menuItemsChoice); System.out.println(selectedMenuItem.getMenuName() + " \t|\t " + selectedMenuItem.getMenuItemsPrice() + " \t|\t " + selectedMenuItem.getMenuDescription()); // 옵션을 가지고 있는지 확인 if (!selectedMenuItem.getOptionMap().isEmpty()) { System.out.println("위 메뉴의 어떤 옵션으로 추가하시겠습니까?"); for (Map.Entry<Integer, Option> entry : selectedMenuItem.getOptionMap().entrySet()) { Option option = entry.getValue(); System.out.println(entry.getKey() + ". " + option.getOptionName() + " \t|\t " + option.getOptionPrice() + "원"); } int optionChoice = sc.nextInt(); if (optionChoice >= 1 && optionChoice <= selectedMenuItem.getOptionMap().size()) { Option selectedOption = selectedMenuItem.getOptionMap().get(optionChoice); MenuItems newItem = new MenuItems(selectedMenuItem.getMenuName(), selectedMenuItem.getMenuDescription(), selectedOption.getOptionPrice(), selectedMenuItem.getMenuItemCount()); order.addToCart(newItem); System.out.println(newItem.getMenuName() + " - " + selectedOption.getOptionName() + "이(가) 장바구니에 추가되었습니다."); System.out.println(); } else { System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } } else { // 옵션이 없는 경우 메뉴를 그대로 추가 MenuItems newItem = new MenuItems(selectedMenuItem.getMenuName(), selectedMenuItem.getMenuDescription(), selectedMenuItem.getMenuItemsPrice(), selectedMenuItem.getMenuItemCount()); order.addToCart(newItem); System.out.println(newItem.getMenuName() + "이(가) 장바구니에 추가되었습니다."); System.out.println(); } } else { System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } } // 장바구니 추가 확인 메서드 public static void orderCheckMethod(Map<Integer, MenuItems> menuItemsMap, int menuItemsChoice, int orderChoice) { switch (orderChoice) { case 1: System.out.println(menuItemsMap.get(menuItemsChoice).getMenuName() + "이(가) 장바구니에 추가되었습니다."); System.out.println(); break; case 2: System.out.println("취소되었습니다. 메뉴판으로 돌아갑니다."); System.out.println(); break; default: System.out.println("잘못된 입력입니다. 메뉴판으로 돌아갑니다."); System.out.println(); } } }
프로젝트를 하면서 Map에 대해 더 잘 알게 되었다.
- 맵을 반복문을 통해 순회하는 방법에 대해 알게 되었다.
- Entry를 이용해 키-값을 같이 순회할 수 있다.
for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); int value = entry.getValue(); System.out.println(key + " => " + value); }
'TIL' 카테고리의 다른 글
23.10.30) TIL - 재귀함수 (0) 2023.10.30 23.10.24) 팀 프로젝트 - 호텔 예약 프로그램 (0) 2023.10.24 23.10.19) TIL - 개인프로젝트(키오스크) (0) 2023.10.19 23.10.18) TIL - 개인프로젝트(키오스크) (1) 2023.10.18 23.10.17) TIL (0) 2023.10.17 댓글