1. 키오스크 만들기
계산기 만들기 과제가 어제 끝났는데 새로운 과제가 발제되었다. 저번 과제는 단계가 세분화 되어있지 않았는데 이번 과제는 꽤나 세분화 되어있었다.
계산기 만들기 때와는 다르게 구현하고싶은 것도 많고 아이디어도 계속 떠올랐다. 다만 어떻게 구현해야할 지 내가 할 수 있을 지 걱정이 되었는데 우선 튜터님이 lv1 부터 차근차근 올라가보라고 하셔서 급하게 lv1 을 구현했다.
1) LV1 프로그래밍 가이드
- 입력 처리와 간단한 흐름 제어 복습
- Scanner를 사용하여 여러 햄버거 메뉴를 출력
- 제시된 메뉴 중 입력받은 숫자에 따라 다른 로직을 실행하는 코드 작성
<구현계획>
- 프로그램 시작 시 주문, 주문취소, 주문내역, 홈 네 가지 선택지가 출력된다.
- 사용자가 주문을 선택하면 하위 선택지에 버거, 사이드, 음료 선택지가 나온다.
- 다시 원하는 메뉴를 선택하면 각각의 선택지에 대한 세부 메뉴가 나온다.
- 메뉴를 고르면 리스트에 저장되어 주문내역에서 확인할 수 있다.
<제한사항>
- 반복문을 이용해 특정 번호가 입력되면 프로그램 종료
↓결과물↓
package kioskTest;
import java.util.ArrayList;
import java.util.Scanner;
/**
* lv1 키오스크 구현. 사용자가 출력된 번호와 메뉴를 선택하면 해당 메뉴가 리스트에 쌓여 출력된다.
*/
public class MainKiosk {
public static void main(String[] args) {
ArrayList<String> orderList = new ArrayList<>(); // 주문 내역 저장
Scanner scanner = new Scanner(System.in);
while (true) {
// 홈 화면 - 4가지 선택지가 있으며 1. 주문을 선택하면 상세 메뉴들이 나온다.
System.out.println("========== 1. 주문 | 2. 주문취소 | 3. 주문내역 | 0. 홈(종료) ==========");
System.out.print("메뉴를 선택하세요: ");
int choice = scanner.nextInt();
if (choice == 1) {
// 1. 주문 -> 하위 메뉴 출력
while (true) {
System.out.println("\n[ 주문 메뉴 ]");
System.out.println("1. 버거 메뉴");
System.out.println("2. 사이드 & 디저트 메뉴");
System.out.println("3. 음료 메뉴");
System.out.println("0. 홈으로 돌아가기");
System.out.print("메뉴를 선택하세요: ");
int subChoice = scanner.nextInt();
if (subChoice == 0) {
System.out.println("홈 화면으로 돌아갑니다.\n");
break; // 상위 메뉴로 돌아가기
} else if (subChoice == 1) {
// 버거 메뉴 -> 메뉴아이템 클래스 (버거, 사ㅣ이드, 음료) 메뉴 클래스로 다리놓기
System.out.println("\n[ 버거 메뉴 ]");
System.out.println("1. TheRealOfficialNewYorkBurger | W 13.5");
System.out.println("2. PiggyCreamBurger | W 14.5");
System.out.println("3. CheeseVolcanoBurger | W 16.5");
System.out.println("4. MacNCheeseBurger | W 14.5");
System.out.println("5. DevilHotBurger | W 14.5");
System.out.println("0. 이전 메뉴로 돌아가기");
System.out.print("메뉴를 선택하세요: ");
int burgerChoice = scanner.nextInt();
if (burgerChoice == 0) {
System.out.println("이전 메뉴로 돌아갑니다.\n");
} else if (burgerChoice >= 1 && burgerChoice <= 5) {
String selectedBurger = switch (burgerChoice) {
case 1 -> "TheRealOfficialNewYorkBurger";
case 2 -> "PiggyCreamBurger";
case 3 -> "CheeseVolcanoBurger";
case 4 -> "MacNCheeseBurger";
case 5 -> "DevilHotBurger";
default -> "";
};
orderList.add(selectedBurger);
System.out.println(selectedBurger + "를(을) 선택했습니다.\n");
} else {
System.out.println("잘못된 입력입니다. 다시 선택해주세요.\n");
}
} else if (subChoice == 2) {
// 사이드 & 디저트 메뉴 출력
System.out.println("\n[ 사이드 & 디저트 메뉴 ]");
System.out.println("1. TexasBarbeque | W 49");
System.out.println("2. ChiliCheeseFries | W 14.5");
System.out.println("3. OnionRing | W 12.5");
System.out.println("4. OreoMilkShake | W 6.5");
System.out.println("5. CornSalad | W 3.5");
System.out.println("0. 이전 메뉴로 돌아가기");
System.out.print("메뉴를 선택하세요: ");
int sideChoice = scanner.nextInt();
if (sideChoice == 0) {
System.out.println("이전 메뉴로 돌아갑니다.\n");
} else if (sideChoice >= 1 && sideChoice <= 5) {
String selectedSide = switch (sideChoice) {
case 1 -> "TexasBarbeque";
case 2 -> "ChiliCheeseFries";
case 3 -> "OnionRing";
case 4 -> "OreoMilkShake";
case 5 -> "CornSalad";
default -> "";
};
orderList.add(selectedSide);
System.out.println(selectedSide + "를(을) 선택했습니다.\n");
} else {
System.out.println("잘못된 입력입니다. 다시 선택해주세요.\n");
}
} else if (subChoice == 3) {
// 음료 메뉴 출력
System.out.println("\n[ 음료 메뉴 ]");
System.out.println("1. 제로콜라 | W 3.5");
System.out.println("2. 코카콜라 | W 3.5");
System.out.println("3. 스프라이트 | W 3.5");
System.out.println("4. 레모네이드 | W 4.5");
System.out.println("5. 자몽에이드 | W 4.5");
System.out.println("0. 이전 메뉴로 돌아가기");
System.out.print("메뉴를 선택하세요: ");
int drinkChoice = scanner.nextInt();
if (drinkChoice == 0) {
System.out.println("이전 메뉴로 돌아갑니다.\n");
} else if (drinkChoice >= 1 && drinkChoice <= 5) {
String selectedDrink = switch (drinkChoice) {
case 1 -> "제로콜라";
case 2 -> "코카콜라";
case 3 -> "스프라이트";
case 4 -> "레모네이드";
case 5 -> "자몽에이드";
default -> "";
};
orderList.add(selectedDrink);
System.out.println(selectedDrink + "를(을) 선택했습니다.\n");
} else {
System.out.println("잘못된 입력입니다. 다시 선택해주세요.\n");
}
} else {
System.out.println("잘못된 입력입니다. 다시 선택해주세요.\n");
}
}
} else if (choice == 2) {
// 2. 주문 취소를 하면 그동안 리스트에 쌓였던 데이터가 모두 삭제된다.
System.out.println("주문이 모두 취소되었습니다.\n");
orderList.clear();
} else if (choice == 3) {
// 3. 주문 내역 출력
System.out.println("\n[ 주문 내역 ]");
if (orderList.isEmpty()) { // 아무것도 선택하지 않은 상태에서는 주문 내역이 없다고 나온다.
System.out.println("현재 주문 내역이 없습니다.\n");
} else {
System.out.println(orderList + "\n");
}
} else if (choice == 0) {
// 0. 프로그램 종료
System.out.println("프로그램을 종료합니다.");
break;
} else {
System.out.println("잘못된 입력입니다. 다시 선택해주세요.\n");
}
}
scanner.close(); // Scanner 닫기
}
}
처참한 결과물. 하고싶은 건 많은데 쓸 수 있는 건 없으니 가장 자신있고 쉬운 if조건문으로 하나하나 모두 작성했다. 작성할 때도 이게 맞나 하면서 짰는데 다 쓰고나니 진짜 하드코딩이다..
물론 내가 프로그래밍 가이드를 안보고 신나서 혼자 마구 짜다가 이런 처참한 코드가 탄생되었다.
실행시켰더니 콘솔창에는 정말 내가 원하는 출력이 나와서 더욱 슬펐다. 영빈님에게 보여드리니 이건 유기적으로 모두 연결되어있어서 뜯어서 클래스로 나누기도 힘들어 보인다고 했다..
사실 나도 코드를 작성하고 나서 클래스로 나누고싶었는데 조건문으로 이어져있어서 뭐 하나를 빼면 모두 무너지게 되는 구조였다.
추가할 수도 뺄 수도 없는 정말 확장성이 떨어지는 절차지향적 코드를 짜버렸다.
하지만 이미 작성했는데 어쩔 수 있나 그냥 객체지향 프로그래밍의 중요성을 깨달은 기회였다고 생각하라는 영빈님..
뼈저리게 느꼈다. 정상적으로 돌아간다고 해서 코드가 멀쩡한 것은 아니다. 변경에 대응하고, 확장성을 가지고, 객체지향적인 코드를 작성하자.
그리고 또 하나, 과제의 의미를 파악하자. 조건문과 반복문을 떡칠해 유지보수에 취약한 코드를 작성하라는 의도는 절대 아니었을텐데..
과제 진행 전, 혹은 내가 맡게 될 다른 프로젝트를 진행하기 전에 나에게 전하고자 하는 메세지, 그것의 의미, 그리고 출제자의 의도를 잘 파악해서 프로젝트를 진행하자.
<문제점>
- 코드의 가독성이 매우 떨어짐
- 모든 코드가 유기적으로 연결되어있는데 클래스가 나눠져있지 않아 유지보수를 하기 힘들고, 변경에 대응하기 힘듦 (확장성 떨어짐)
<해결방안, 개선점>
- 각 기능 별로 클래스를 세분화 하여 상황에 유연하게 대처하고 확장성을 높인다.
- 객체 지향 프로그래밍으로 데이터를 구조적으로 관리하여 프로그램을 설계한다.
- 과제에서 요구하는 사항을 꼼꼼히 파악하고 이를 프로그래밍에 녹여낼 수 있게 한다.
<잘한 점>
- 변수의 이름이 직관적이다.
- 상위 메뉴에서 하위 메뉴로 점점 들어가는 구조도 아주 좋다.
물론 잘한 점은 스스로 생각하는 거지만.. 코드를 개선시킬 때도 이어나갈 예정이라.. 칭찬해봤다 :)
★새배개 ★
1. JavaDoc : /** 내용 */ 형식으로 작성하며, Java 소스코드에서 API문서를 html태그 형식으로 작성하게 해주는 도구. 컴파일 시 모든 주석은 지워지므로 프로그램 성능에는 영향이 없다.
annotaion | Description | Example |
@version | 구현체(클래스, 메소드,변수 등)의 버전 | 외부 링크 : a href 태그 이용 내부 참조 : 패키지명#생성자/ 필드 / 메소드명 |
@author | 작성자 | |
@deprecated | 해당 구현체가 곧 삭제, 업데이트 중단을 의미 | |
@since | 해당 구현체가 추가된 버전 | |
@see | 외부 링크나 텍스트, 다른 필드나 메소드를 링크할 때 사용 | |
@link | see와 동일한 기능, 참조에 대한 링크 제공 | |
@exception | 발생할 수 있는 Exception 정의 | |
@throws | 코드에서 throw 할 수 있는 예외상황 정의 | |
@param | 메소드의 매개변수 / 인자값 설명 | |
@return | 반환값 | |
@serial | Serializable Interface에 사용 | |
@serialDate | writeObject writeExternal 메소드로 작성된 추가적 데이터를 설명 | |
@serialField | serialPersistnetFields 배열의 모든 필드에 사용 |
'내일배움캠프 > TIL' 카테고리의 다른 글
[Spring_4기 본캠프] 키오스크 과제&트러블 슈팅 | Day 27 (0) | 2024.11.25 |
---|---|
[Spring_4기 본캠프] 기본형과 참조형, final | Day 26 (0) | 2024.11.22 |
[Spring_4기 본캠프] 3주차 - 계산기 lv2와 트러블 슈팅 | Day 24 (1) | 2024.11.19 |
[Spring_4기 본캠프] 3주차 - 계산기 lv2 | Day 23 (0) | 2024.11.19 |
[Spring_4기 본캠프] 3주차 - 컬렉션 | Day 22 (0) | 2024.11.17 |