TIL
[250313 TIL] 키오스크 기능 추가 및 개선
도원좀비
2025. 3. 13. 19:52
🛠 ReturnToHomeException을 활용한 홈 이동 구현
🔥 기존 문제점
- 홈 이동(-1)을 선택했을 때, 단순히 start();로 새로운 start메서드를 호출
- 기존 메서드는 종료되지 않고 계속 남아있어서 메모리 낭비 및 무한 루프 위험
💡 해결 방법
- 홈 이동을 예외 처리(ReturnToHomeException)를 이용하여 강제 실행 흐름 종료
- start()에서 try-catch를 사용하여 예외가 발생하면 홈으로 이동하도록 설정.
더보기
ReturnToHomeException.java
// 홈 이동 예외 클래스 생성
public class ReturnToHomeException extends RuntimeException {
public ReturnToHomeException() {
super("홈으로 이동");
}
}
Kiosk.java
// 뒤로 가기 및 홈 이동 처리
private boolean checkNavigationOption(int option) {
if (option == OPTION_HOME) {
System.out.println("홈으로 이동합니다.");
throw new ReturnToHomeException();
}
if (option == OPTION_BACK) {
System.out.println("이전 화면으로 이동합니다.");
return true;
}
return false; // 홈으로 가지 않음
}
🚫잘못된 해결법(재귀함수 오버플로우 발생가능)
// 키오스크 메인 실행 메서드
public void start() {
try {
while (true) {
displayMainMenu(); // 메인 메뉴 출력
System.out.print("메뉴를 선택해주세요 : ");
int option = getValidIntInput(); // 사용자 입력 받기
switch (option) {
case 1 -> selectCategory(); // 카테고리 선택
case 2 -> viewCart(); // 장바구니 보기
case 3 -> checkout(); // 주문하기
case 4 -> orderHistory.displayOrdersList(); // 주문 내역 출력
case 0 -> { // 종료
System.out.println("프로그램을 종료합니다.");
return;
}
default -> System.out.println("잘못된 입력입니다. 다시 선택해주세요.");
}
}
} catch (ReturnToHomeException e) {
// 홈 이동 예외 발생 시 start() 실행을 강제 종료
System.out.println("\n 홈 화면으로 돌아갑니다.\n");
start(); // 다시 start() 실행
}
}
🎯옳은 해결 법 재귀함수 문제 해결(새로 호출하는게 아닌 기존 start메서드 활용)
// 키오스크 메인 실행 메서드
public void start() {
while (true) {
try {
displayMainMenu(); // 메인 메뉴 출력
System.out.print("메뉴를 선택해주세요 : ");
int option = getValidIntInput(); // 사용자 입력 받기
switch (option) {
case 1 -> selectCategory(); // 카테고리 선택
case 2 -> viewCart(); // 장바구니 보기
case 3 -> checkout(); // 주문하기
case 4 -> orderHistory.displayOrdersList(); // 주문 내역 출력
case 0 -> { // 종료
System.out.println("프로그램을 종료합니다.");
return;
}
default -> System.out.println("잘못된 입력입니다. 다시 선택해주세요.");
}
} catch (ReturnToHomeException e) {
System.out.println("\n 홈 화면으로 돌아갑니다.\n");
}
}
}
✅ 홈 이동이 필요할 때 예외를 발생시키면, 모든 실행 흐름이 종료된 후 start()가 다시 실행되어 홈 화면으로 이동
✅ 무한 루프 위험이 제거되어 기존의 방식보다 훨씬 안전하게 실행된다.
💰 결제(PaymentMethod) 시스템
➕ 추가 기능
- 결제 방식 선택 기능 추가
- 할인 적용 기능 개선 (applyDiscount())
더보기
PamentMethod.java
package kioskLv6;
public enum PaymentMethod {
CARD("카드"),
CASH("현금"),
MOBILE("모바일 결제");
private final String method;
PaymentMethod(String method) {
this.method = method;
}
public String getMethod() {
return method;
}
public static void displayPaymentOption() {
int i = 1;
for (PaymentMethod method : PaymentMethod.values()) {
System.out.printf("%d. %s\n", i++, method.getMethod());
}
}
}
📝 4. 주문(Order) 및 주문 내역(OrderHistory) 기능
➕ 추가 기능
- 주문 후 자동으로 영수증 출력
- 주문 내역 확인 기능 추가
더보기
Order.java
package kioskLv6;
import java.util.LinkedHashMap;
import java.util.Map;
public class Order {
// 속성
private static Integer ORDER_SEQUENCE = 1;
private final Integer orderNumber;
private final Map<MenuItem, Integer> items;
private final Discount discount;
private final PaymentMethod paymentMethod;
private final Double totalPrice;
// 생성자
public Order(Map<MenuItem, Integer> items, Discount discount, PaymentMethod paymentMethod, Double totalPrice) {
this.orderNumber = ORDER_SEQUENCE++;
this.items = new LinkedHashMap<>(items);
this.discount = discount;
this.paymentMethod = paymentMethod;
this.totalPrice = totalPrice;
}
// 기능
// 영수증 출력
public void printReceipt() {
System.out.println("\n===== 영수증 =====");
System.out.println("주문 번호: " + orderNumber);
items.forEach((item, count) ->
System.out.printf("%s | %d개 | W %d\n",
item.getName(), count, item.getPrice() * count));
System.out.println("------------------");
System.out.println("할인: " + discount.getDiscountCategory());
System.out.println("결제 방법: " + paymentMethod.getMethod());
System.out.println("총 결제 금액: W " + totalPrice);
System.out.println("=================\n");
}
}
OrderHistory.java
package kioskLv6;
import java.util.LinkedHashMap;
import java.util.Map;
public class Order {
// 속성
private static Integer ORDER_SEQUENCE = 1;
private final Integer orderNumber;
private final Map<MenuItem, Integer> items;
private final Discount discount;
private final PaymentMethod paymentMethod;
private final Double totalPrice;
// 생성자
public Order(Map<MenuItem, Integer> items, Discount discount, PaymentMethod paymentMethod, Double totalPrice) {
this.orderNumber = ORDER_SEQUENCE++;
this.items = new LinkedHashMap<>(items);
this.discount = discount;
this.paymentMethod = paymentMethod;
this.totalPrice = totalPrice;
}
// 기능
// 영수증 출력
public void printReceipt() {
System.out.println("\n===== 영수증 =====");
System.out.println("주문 번호: " + orderNumber);
items.forEach((item, count) ->
System.out.printf("%s | %d개 | W %d\n",
item.getName(), count, item.getPrice() * count));
System.out.println("------------------");
System.out.println("할인: " + discount.getDiscountCategory());
System.out.println("결제 방법: " + paymentMethod.getMethod());
System.out.println("총 결제 금액: W " + totalPrice);
System.out.println("=================\n");
}
}
✅ 주문이 완료되면 자동으로 영수증을 출력하도록 개선
✅ 주문 내역(OrderHistory)를 통해 지난 주문을 확인할 수 있도록 구현