어제에 이어 키오스크 프로그램을 추가로 구현하면서 생각대로 구현하는 게 어렵다는 것을 다시 한 번 깨달았다. 이렇게 저렇게 하면 되지 않을까? 하다가도 그 생각을 그대로 구현한다는게 얼마나 힘들던지.. 🥹 지금 하고 있는 키오스크 프로그램의 경우 아직 3단계까지 밖에 못 했는데 천천히라도 남은 단계를 마저 마무리 하고 구현하면서 새로 접하는 부분들을 잘 정리해야겠다 !
처음에는 name, price, explain 속성만 사용하려고 했는데 카테고리별 아이템을 출력할 때 아이템의 인덱스값이나 아이템을 검색하는 부분에 있어서 문제가 발생하여 인덱스와 문자열 타입의 카테고리를 추가하게 되었다.
abstract class AbstractMenu(val id: Int, val category: String, val name: String, val price: Int, val explain: String) {
abstract fun displayInfo(): String
}
class MenuManage(private val abstractMenu: AbstractMenu) {
fun displayInfo(): String {
return abstractMenu.displayInfo()
}
}
class ProductManage {
private val products: ArrayList<AbstractMenu> = initProduct()
private fun initProduct(): ArrayList<AbstractMenu> {
val products = ArrayList<AbstractMenu>()
val burger = arrayListOf<AbstractMenu>(
Burger(0, "burger", "빅맥", 5500, "100% 순 쇠고기 패티 두 장에 치즈, 양상추, 피클"),
Burger(1, "burger", "맥크리스피 디럭스 버거", 6800, "100% 통다리살 케이준 치킨 패티, 포테이포 브리오쉬 번"),
Burger(2, "burger", "맥크리스피 상하이 버거", 5500, "100% 닭가슴살 통살 위에 양상추, 토마토, 치킨 패티")
)
val beverage = arrayListOf<AbstractMenu>(
Beverage(0, "beverage", "아메리카노", 1000, "바로 내린 100% 친환경 커피로 더 신선하게! 더 풍부하게!", "스몰"),
Beverage(1, "beverage", "아메리카노", 1500, "바로 내린 100% 친환경 커피로 더 신선하게! 더 풍부하게!", "미디엄"),
Beverage(2, "beverage", "카페라떼", 1500, "바로 내린 100% 친환경 커피가 신선한 우유를 만나 더 신선하고 부드럽게!", "스몰") ,
Beverage(3, "beverage", "카페라떼", 2000, "바로 내린 100% 친환경 커피가 신선한 우유를 만나 더 신선하고 부드럽게!", "미디엄"),
Beverage(4, "beverage", "코카콜라", 1700, "갈증해소 뿐만이 아니라 기분까지 상쾌하게! 코카-콜라", "스몰"),
Beverage(5, "beverage", "코카콜라", 2200, "갈증해소 뿐만이 아니라 기분까지 상쾌하게! 코카-콜라", "미디엄")
)
val fried = arrayListOf<AbstractMenu>(
Fried(0, "fried", "골든 모짜렐라 치즈스틱", 2000, "자연 모짜렐라 치즈로 빈틈 없이 고소한 치즈스틱", "2조각"),
Fried(1, "fried", "골든 모짜렐라 치즈스틱", 4200, "자연 모짜렐라 치즈로 빈틈 없이 고소한 치즈스틱", "4조각"),
Fried(2, "fried", "맥너겟", 2600, "바삭하고 촉촉한 치킨이 한 입에 쏙", "4조각"),
Fried(3, "fried", "맥너겟", 3800, "바삭하고 촉촉한 치킨이 한 입에 쏙", "6조각"),
)
products.addAll(burger)
products.addAll(beverage)
products.addAll(fried)
return products
}
fun displayMain() {
val category = arrayListOf("Burger", "Side & Dessert", "Mac Cafe & Beverage")
val explain = arrayListOf(
"주문 즉시 바로 조리해 더욱 맛있는, 맥도날드의 다양한 버거를 소개합니다.",
"버거와 함께 즐기면 언제나 맛있는 사이드와 디저트 메뉴!",
"언제나 즐겁게, 맥카페와 다양한 음료를 부담없이 즐기세요!"
)
println(
"\n아래 메뉴판을 보시고 메뉴를 골라 입력해주세요. \n\n" +
"[ McDonald's's MENU ]"
)
for (i in category.indices) {
println("%d. %-20s | %s".format(i + 1, category[i], explain[i]))
}
println("%d. %-20s | %s".format(0, "종료", "프로그램 종료"))
}
fun displayMenu(menu: String) { // 선택된 메뉴
products.filter { it.category == menu }.forEach {
println("${it.id + 1}. ${MenuManage(it).displayInfo()}")
}
println("%d. %-10s | %s".format(0, "뒤로가기", "뒤로가기"))
}
fun displayItem(item: AbstractMenu?) {
if (item == null) {
println("선택한 상품이 존재하지 않습니다. 관리자에게 문의해주세요.")
} else {
println("\" ${item.displayInfo()} \"")
item.displayInfo()
// println("위 메뉴를 장바구니에 추가하시겠습니까?")
}
}
fun getSelectedItem(menu: String, id: Int): AbstractMenu? {
return products.filter { it.category == menu }.find { it.id == id - 1 }
}
fun getMenuCount(menu: String): Int {
return products.count { it.category == menu }
}
}
class Beverage(id: Int, category: String, name: String, price: Int, explain: String, private val size: String) :
AbstractMenu(id, category, name, price, explain) {
override fun displayInfo(): String {
return "%s - %-5s| ₩ %4d | %s".format(name, size, price, explain)
}
}
처음에는 displayInfo() 함수를 반환값이 없는 타입으로 만들고 안에서 문자열을 출력하였다. 해당 함수에서 당장 정보를 출력해주는 것보다 문자열을 반환하여 외부에서 문자열을 새로 조합하는 게 나을 것 같아 함수를 수정하게 되었다.
class Burger(id: Int, category: String, name: String, price: Int, explain: String) :
AbstractMenu(id, category, name, price, explain) {
override fun displayInfo(): String {
return "%-10s | ₩ %4d | %s".format(name, price, explain)
}
}
class Fried(
id: Int,
category: String,
name: String,
price: Int,
description: String,
private val size: String
) :
AbstractMenu(id, category, name, price, description) {
override fun displayInfo(): String {
return "%s - %-5s| ₩ %4d | %s".format(name, size, price, explain)
}
}
fun main() {
val productManage = ProductManage()
while (true) {
productManage.displayMain()
val input = readln()
var select: Int
if (input.isNumber()) {
select = input.toInt()
} else {
continue
}
when (select) {
0 -> {
println("프로그램을 종료 합니다.")
break
}
1 -> {
println("\n[ Burger MENU ]")
productManage.displayMenu("burger")
while (true) {
val enter = readln()
var number: Int
if (enter.isNumber()) {
number = enter.toInt()
} else {
continue
}
if (number == 0) {
break
} else if (number < 0 || number > productManage.getMenuCount("burger")) {
println("잘 못 된 번호를 입력했어요. 다시 입력해주세요.")
} else {
val item = productManage.getSelectedItem("burger", number)
productManage.displayItem(item)
break
}
}
}
2 -> {
println("\n[ Fried MENU ]")
productManage.displayMenu("fried")
while (true) {
val enter = readln()
var number: Int
if (enter.isNumber()) {
number = enter.toInt()
} else {
continue
}
if (number == 0) {
break
} else if (number < 0 || number > productManage.getMenuCount("fried")) {
println("잘 못 된 번호를 입력했어요. 다시 입력해주세요.")
} else {
val item = productManage.getSelectedItem("fried", number)
productManage.displayItem(item)
break
}
}
}
3 -> {
println("\n[ Beverage MENU ]")
productManage.displayMenu("beverage")
while (true) {
val enter = readln()
var number: Int
if (enter.isNumber()) {
number = enter.toInt()
} else {
continue
}
if (number == 0) {
break
} else if (number < 0 || number > productManage.getMenuCount("beverage")) {
println("잘 못 된 번호를 입력했어요. 다시 입력해주세요.")
} else {
val item = productManage.getSelectedItem("beverage", number)
productManage.displayItem(item)
break
}
}
}
else -> {
println("잘 못 된 번호를 입력했어요. 다시 입력해주세요.")
}
}
}
}
fun String.isNumber(): Boolean {
return try {
this.toInt()
true
} catch (e: NumberFormatException) {
println("잘 못 된 문자 타입을 입력했어요. 다시 입력해 주세요.")
false
}
}