본문 바로가기
앱개발/안드로이드

[Kotlin] 실습. 키오스크 프로그래밍 구현해보자.

by 큌 2024. 3. 9.
반응형


▷ 각 클래스의 설명




  1. Banking.kt : 은행 업무 처리 시간(매일 23시 10분 ~23시 20분) 동안에만 처리가 불가능한지를 판단하는 기능이다.
  2. Beverage.kt : MenuItem 클래스를 상속 받아 음료 정보(id, 이름, 가격, 카페고리, 설명)를 담고 있다.
  3. Cancel.kt : 전달 받은 Cart 객체에 포함된 주문을 전체 취소 혹은 특정 인덱스 기준으로 주문 취소를 처리하는 기능이다.
  4. Cart.kt : MenuItem 객체를 저장하는 Cart 클래스를 생성하며, 항목을 카트에 추가하는 기능을 수행한다.
  5. Deley.kt : 주어진 작업(block)을 3초의 딜레이 후 실행하는 기능을 수행한다.
  6. Main.kt : MenuManager와 MenuHandler 객체를 생성한 후, MenuHandler 객체의 handleMenu() 함수를 호출하여 메뉴 관리 작업을 처리하는 기능을 수행한다.
  7. MainMenu.kt : 스타벅스 메뉴판과 주문 옵션을 화면에 출력하는 display() 함수를 가지고 있다.
  8. MenuHandler.kt : 메뉴 핸들링, 주문 처리, 결제, 취소, 중지 등 사용자의 선택에 따라 키오스크를 조작하고 관리하는 기능을 수행한다.
  9. MenuItem.kt : 메뉴 아이템의 정보(아이디, 이름, 가격, 카테고리, 설명)를 가지고 있으며, display() 함수를 사용해 메뉴 아이템의 이름과 가격을 표시할 수 있는 기능을 수행한다.
  10. MenuManager.kt : 여러 카테고리의 메뉴 아이템을 관리하고, 해당 카테고리를 기반으로 메뉴 아이템을 표시하거나 검색하는 기능을 수행한다.
  11. Order.kt : 주문 관련 기능을 수행하며 장바구니 내용을 기반으로 총 결제 금액 계산, 주문 사항 출력, 잔액 확인, 주문 처리, 주문 취소, 그리고 대기 주문 수 확인 기능을 수행한다.


 Main.kt




com.example.kiosk 패키지에 포함된 Android 어플리케이션의 진입점(main)함수이다.

메뉴 아이템을 관리하는 MenuManager 인스턴스 생성
사용자와 상호작용하며 메뉴 선택을 처리하는 MenuHandler 인스턴스 생성하고, 이전에 생성한 MenuHandler 인스턴스를 전달
MenuHandler의 handleMenu 메소드를 호출하여 메뉴 선택 처리 시작하여 사용자의 입력에 따라 메뉴 표시 및 주문 처리 진
@RequiresApi(Build.VERSION_CODES.O) 애너테이션이 필요한 이유는 이 코드가 Android 버전 8.0 이상에서만 작동한다는 것을 명시하기 위해서이다.


 MenuItem.kt





  1. id : 메뉴 아이템의 고유 번호
  2. name : 메뉴 아이템의 이름
  3. price : 메뉴 아이템의 가격
  4. category : 메뉴 아이템이 속한 카테고리
  5. description : 메뉴 아이템에 대한 설명
  6. display() : 메뉴 아이템의 이름과 가격을 표시하는 함수로 문자열을 반환한다.



 Beverage.kt




Beverage 클래스는 MenuItem 클래스의 모든 속성과 함수를 상속 받는다.
Beverage 클래스의 생성자는 id, name, price, category, description 매개변수를 받아 MenuItem 클래스의 생성자에 전달한다.

즉, MenuItem 클래스는 메뉴 아이템에 대한 기본 정보를 나타내며, Beverage 클래스는 음료에 대한 정보를 나타내는 클래스이다. Beverage 클래스는 현재 추가적인 속성이나 메서드가 없지만 차후 개발 과정에서 음료 관련 특성을 추가할 수 있다.


 MainMenu.kt




ManiMenu 클래스는 사용자에게 메인 메뉴를 표시하는 역할을 한다.


 MenuManager.kt




MenuManager 클래스는 메뉴 아이템을 관리하는 역할을 한다.

  1. menuItems : 모든 메뉴 아이템을 저장하는 ArrayList 타입의 private 속성이다.
  2. init 블록 : 클래스의 인스턴스가 생성될 때 실행되며, 여러 카테고리별 음료가 menuItems에 추가된다. 각 카테고리(COFFEE & ESPRESSO, FRAPPUCCINO & BLENDED, TEAVANA & COFFEE, COLD BREW & CHOCOLATE )는 각각의 Beverage 객체를 포함하는 ArrayList이다. 그 후, 이 카테고리들은 모두 menuItems에 추가된다.


 MenuManager.kt




  1. displayMenu(category: String) 함수는 인자로 전달된 category에 해당하는 메뉴 아이템들만을 필터링하고, 이들을 화면에 출력한다. 또한, "0. 뒤로가기" 옵션도 추가로 출력한다.
  2. findByIdAndCategory(id: Int, category: String): MenuItem? 함수는 인자로 전달된 category에 해당하는 메뉴 아이템들의 개수를 반환한다. Kotlin에서 ? 기호는 nullability를 나타낸다. 코드에 있는 MenuItem?에서, ?는 반환되는 MenuItem 객체가 null 일 수 있다는 것을 나타낸다. 이는 호출자가 이 함수의 결과를 처리할 때, 반환값이 null일 수 있음을 유의해야 함을 알리고, 이에 대한 처리를 추가할 수 있게 한다.
  3. getCategorySize(category: String): Int 함수는 인자로 전달된 category에 해당하는 메뉴 아이템들의 개수를 반환한다.


 Cart.kt




Cart 클래스는 사용자가 선택한 메뉴 아이템을 카트에 추가하고 관리하는 역할을 한다.

items은 선택된 메뉴 아이템을 저장하는 mutableListOf 타입의 속성이다. 이렇게 mutableListOf를 사용하면 컬렉션에 항목을 추가하거나 제거할 수 있다.
addItem(item: MenuItem): 인자로 전달된 item을 items 목록에 추가하는 함수이다. 이 함수를 호출해 메뉴 아이템을 카트에 추가할 수 있다.


Order.kt




Order 클래스를 통해 사용자는 주문한 음료의 총 가격을 계산하고, 주문을 출력 및 처리한다. 또한, 주문이 취소되는 경우 이를 처리하고 대기 중인 주문 수를 조회할 수 있다.

cart는 주문에 포함된 장바구니를 나타내는 Cart 타입의 private 속성이다.
orderCount는 주문할 항목의 수를 나타내는 private 속성이다.
calculateTotalPrice()는 카트에 있는 모든 메뉴 아이템의 가격을 합산해 총 주문 가격을 계산하는 함수이다.
printOrder()는 주문한 메뉴 아이템을 출력한다.
hasSufficientBalance(currentBalance: Double)은 입력된 currentBalance가 주문의 총 금액보다 크거나 같은지 확인하는 함수이다. 충분한 잔고가 있는 경우 true를 반환하고, 그렇지 않으면 false 반환한다.
processOrder(currentBalance: Double)은 주문을 처리하는 함수이다. 잔고가 충분한 경우 주문 사항을 출력하고, 주문이 완료되었다는 메시지를 출력한다. 또한, 주문이 완료된 후 남은 작액도 출력된다. 잔액이 부족한 경우, 부족한 금액과 함께 주문할 수 없다는 메시지를 출력한다.
onOrderCancelled()은 주문이 취소된 경우 호출되는 함수로 orderCount를 1 감소시킨다.
getNumberOfWaitingOrders()는 대기 중인 주문 수를 반환하는 함수이다.


 Cancel.kt




Order 클래스를 통해 사용자는 주문 전체를 취소하거나, 특정 음료를 취소할 수 있다.

cart는 취소할 장바구니를 나타내는 Cart 타입의 private 속성이다.
cancelAll()은 카트에 있는 모든 메뉴 아이템을 취소하는 함수이다. cart.items.clear()를 사용해 카트에 있는 모든 아이템을 지우고 주문이 모두 취소되었다는 메시지를 출력한다.
cancelByIndex(index: Int)는 인덱스에 따라 특정 메뉴 아이템을 취소하는 함수이다. 입력된 인덱스가 유효한 범위에 있는 경우 해당 인덱스의 메뉴 아이템을 제거하며, 그 아이템의 이름을 출력하여 아이템이 취소되었음을 알린다. 유효하지 않은 인덱스를 입력한 경우, 잘못된 번호를 입력했다는 메시지를 출력한다.


 Banking.kt




Banking 클래스는 은행 업무 시간에 관련된 처리를 담당한다.

canProcess()는 은행 업무 처리 가능 여부를 확인하는 함수로 (현재 시간과 은행 체크 시작 및 종료 시간) 간의 관계를 통해 은행 업무 처리가 가능한 지 여부를 확인한다.

currentTime은 현재 시간과 날짜를 나타내는 Calendar 인스턴스이다.
bankCheckStartTime은 은행 업무를 체크하기 시작하는 시간을 나타내는 Calendar 인스턴스이다. 이 예제에서는 23시 10분으로 설정되어 있다.
bankCheckEndTime은 은행 업무를 체크하기 끝나는 시간을 나타내는 Calendar 인스턴스이다. 이 예제에서는 23시 20분으로 설정되어 있다.

canProcess() 함수는 현재 시간이 시작 시간 이후 및 종료 시간 이전이 아닌 경우에만 업무 처리가 가능하다고 판단한다. 그래서 !currentTime.after(bankCheckStartTime)과 currentTime.before(bankCheckEndTime) 모두 true이면 false를 반환하고, 그렇지 않으면 true를 반환한다.


 Delay.kt




Delay 클래스는 coroutine을 사용해 일정 시간 딜레이 후 특정 작업을 수행한다. 함수 내부에서 코루틴에서 delay(3000)를 호출하여 코루틴을 3초(3000 밀리초) 동안 지연시킨다.

execute(block: () -> Unit)는 일정 시간 딜레이 후 입력된 람다 함수 block을 실행하는 역할을 한다. block은 () -> Unit 타입의 함수이다.
runBlocking은 코루틴 실행에 필요한 CoroutineScope를 제공하는 블록이다. 이 블록이 종료되기 전까지 메인 스레드를 블록한다.
launch는 새로운 코루틴을 생성하고 시작한다. 여기서 CoroutineScope에서 코루틴을 실행한다.



 MenuHandler.kt






MenuHandler 클래스는 카페 키오스크의 메뉴를 처리한다.

menuManager, cart, order, currentBalance, cancel, delay, banking, dateFormat: MenuHandler에서 사용되는 여러 객체 및 속성이다. 이들은 메뉴, 카트, 주문, 취소, 딜레이 및 은행 시간과 관련된 작업을 실행하는 데 필요한 클래스 객체들이다.@RequiresApi(Build.VERSION_CODES.O) fun handleMenu()는 사용자가 메뉴를 탐색하고 제품을 선택하고 주문을 처리하는 작업을 수행한다. 사용자로부터 선택을 입력 받아, 각 선택에 따라 다양한 동작을 처리한다.메뉴 선택(1, 2, 3, 4)에 따라 대응되는 메뉴 카테고리의 문자열을 menuChoiceCategory 변수에 저장한다.








이 코드 부분은 MenuHandler 클래스 내에서 사용자가 메뉴의 특정 카테고리를 선택한 후, 해당 카테고리의 상품 목록 중에서 원하는 상품을 선택하는 부분이다.

menuManager.displayMenu(menuChoiceCategory): 사용자가 선택한 메뉴 카테고리의 상품 목록을 출력한다.

val beverageChoice = readLine()?.toIntOrNull(): 사용자에게 상품 번호를 입력받는다.

if (beverageChoice != null): 사용자의 입력이 숫자로 변환 가능한지 확인합니다. 숫자가 아니면 "잘못된 입력입니다."라는 메시지를 출력한다.

when (beverageChoice): 사용자가 입력한 상품 번호로 다음 동작들을 수행한다: 0: "뒤로 가기" 메시지를 출력하고 이전 메뉴로 돌아간다.

1부터 menuManager.getCategorySize(menuChoiceCategory)까지: 사용자가 선택한 카테고리와 상품 번호에 해당하는 상품 정보를 가져온다. 그리고 상품 이름, 가격, 설명을 출력한 다음, 사용자에게 장바구니에 상품을 추가할지 물어본다.

1을 입력하면, cart.addItem(it)를 호출하여 장바구니에 상품을 추가하고 상품이 추가된 것을 알리는 메시지를 출력한다.

2을 입력하면, 상품을 추가하지 않고 계속 다른 상품을 선택할 수 있다.

위에 해당하지 않는 숫자를 입력하면 "잘못된 번호를 입력하셨습니다."라는 메시지를 출력한다.

이 코드는 특정 카페 메뉴 카테고리를 선택하고, 해당 카테고리 내의 상품을 장바구니에 추가하는 기능을 구현하며, 사용자가 쉽게 상품을 탐색하고 선택할 수 있다.









이 코드 부분은 사용자가 주문을 확인하고 결제하는 과정을 처리하는 부분이다.

5 ->: 이 부분은 사용자가 주문 확인 및 결제를 선택한 경우에 해당한한다.

order.printOrder(): 현재 장바구니에 담긴 모든 상품과 총 가격을 출력한다.

사용자에게 주문을 진행할지 물어봅니다. 주문 대기 수도 같이 출력한다.

val userChoice = readLine()?.toIntOrNull(): 사용자로부터 1(주문) 또는 2(메뉴판)를 입력받는다.

사용자가 1(주문)을 선택한 경우:

banking.canProcess(): 현재 은행 결제 시스템이 점검 중인지 확인한다.

점검 중이 아니면, order.processOrder(currentBalance)를 호출하여 결제를 진행하고, delay.execute를 통해 결제 완료 메시지를 출력한다.

점검 중이면, 현재 시각과 점검 시간을 알려주고 결제할 수 없다는 메시지를 출력한다.

사용자가 2(메뉴판)을 선택한 경우

continue@outer를 통해 루프를 계속하고 메뉴판 화면으로 돌아간다.

사용자가 잘못된 입력을 한 경우

"잘못된 입력입니다."라는 메시지를 출력하고, 메뉴판 화면으로 돌아간다.

이 코드는 주문 확인, 결제, 은행 점검 시간 처리 등의 기능을 구현하며, 사용자가 주문한 상품들을 확인하고 쉽게 결제할 수 있다.










이 코드 부분은 사용자가 주문을 취소하는 과정을 처리하는 부분이다.

6 -> 이 부분은 사용자가 주문 취소를 선택한 경우에 해당한다.

사용자에게 취소 옵션을 제공하고 입력을 받는다.

1: 전체 취소

2: 품목별 취소

다른 값: 취소하지 않음

when (cancelChoice): 사용자가 선택한 취소 옵션에 따라 다음 동작을 수행한다.

1 (전체 취소): cancel.cancelAll()을 호출하여 장바구니에 있는 모든 상품을 취소하고, order.onOrderCancelled()를 호출하여 주문 취소 처리를 한다.

2 (품목별 취소): 장바구니에 있는 모든 상품을 출력하고, 사용자에게 취소할 항목의 번호를 입력받습니다. 입력받은 번호에 해당하는 상품을 cancel.cancelByIndex(it - 1)를 호출하여 취소하고, order.onOrderCancelled()를 호출하여 품목별 주문 취소 처리를 한다.

그 외의 값: 취소 처리를 진행하지 않고 "취소 여부를 취소하셨습니다."라는 메시지를 출력한다.

0 -> println("프로그램을 종료합니다."): 사용자가 0을 입력하면 프로그램 종료를 알리는 메시지를 출력한다.

else -> println("잘못된 번호를 입력했어요. 다시 입력해주세요."): 사용자가 잘못된 번호를 입력한 경우, 에러 메시지를 출력한다.

do-while (menuChoice != 0) loop: 사용자가 0(프로그램 종료)을 입력하기 전까지 메뉴 선택 과정을 반복한다.

이 코드는 주문을 취소하는 기능을 구현하며, 사용자가 전체 주문을 취소하거나 특정 품목을 취소할 수 있다.

반응형