2025. 1. 16. 22:05ㆍ개발 회고/TIL
😊오늘 배운 내용
자바 문법 5주차 완강, 자바 메모리 세션(static을 왜 사용하면 안되는가 stack,heap,nativememory), 키오스크 과제 level6
[어떤 문제가 있었는지 + 어떻게 해결하였는지]
1. 오늘도 역시나 키오스크 과제 요구사항을 보니 머리로 잘 이해가 안됬다. 물론 예시 출력이 있어서 그걸 보면서 어떻게 동작해야할지 로직을 따로 정리해보았다.
이렇게 정리하고 나니 로직을 어떻게 짜야할 지 눈에 보였고 중간중간 코드 작성하면서 어떻게 해야하지?하고 헷갈릴 때는 이 노트를 다시 보았다.
코드
package org.example.level6;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Kiosk {
//필드
private List<Menu> menu = new ArrayList<>(); //메뉴 객체들을 관리하는 리스트
private List<MenuItem> shoppingCart = new ArrayList<>(); //선택된 MenuItem객체들을 관리하는 리스트(장바구니)
//생성자
public Kiosk(Menu ... menus) {
//키오스크 객체 생성시 여러개의 Menu객체들을 받아와 menu리스트에 add
for (Menu a : menus) {
menu.add(a);
}
}
//메서드
//키오스크 프로그램의 전반적인 흐름을 담당하는 메서드
public void start () {
Scanner sc = new Scanner(System.in);
//입력받는 변수들 선언
int menuChoice;
int cartChoice;
int orderChoice;
int finalChoice;
while (true) {
//카테고리 출력
showCategory();
try {
//카테고리 입력
int categoryChoice = sc.nextInt();
if (categoryChoice == 0) { //0입력받으면 프로그램 종료 (가장 바깥의 while 문 탈출)
break;
} else if (categoryChoice == 1 || categoryChoice == 2 || categoryChoice == 3) {
while (true) {
//메뉴 출력
showMenu(menu,categoryChoice);
//메뉴 선택
System.out.println("메뉴를 선택하세요: ");
menuChoice = sc.nextInt();
if (menuChoice == 0) {
break; //0입력 시 다시 카테고리 출력으로 되돌아감
} else {
//선택된 메뉴 출력
//menuChoice에서 입력예외가 발생할 경우 showSelectedMenu에서 예외가 일어나기 때문에
//따로 예외를 발생시키진 않았음
showSelectedMenu(categoryChoice,menuChoice);
//장바구니 추가 로직
System.out.println("위 메뉴를 장바구니에 추가하시겠습니까?");
System.out.println("1. 확인 2. 취소");
cartChoice = sc.nextInt();
if (cartChoice == 1) {
addShoppingCart(menu.get(categoryChoice-1).getMenuItems().get(menuChoice)); //장바구니 리스트에 추가
showCategory(); //다시 카테고리 출력
showOrderMenu(); //ORDER MENU 출력
//orderChoice 입력
orderChoice = sc.nextInt();
if (orderChoice == 4) {
System.out.println("아래와 같이 주문하시겠습니까?\n");
//장바구니에 담긴 메뉴들 출력
showShoppingCartMenu(shoppingCart);
//finalChoice 입력
System.out.println("1. 주문 2. 메뉴판");
finalChoice = sc.nextInt();
if (finalChoice == 1) {
//주문완료 메세지 + 총 금액 출력
System.out.println("주문이 완료되었습니다. 총 금액은 W" + calculateTotal(shoppingCart) + "입니다. " );
//장바구니 비워주기
shoppingCart.clear();
} else if (finalChoice == 2) {
break; //while문을 탈출해 다시 showCategory()로
} else {
throw new Exception(); // 그 외의 경우 예외발생
}
} else if (orderChoice == 5) {
//주문 취소
System.out.println("주문이 취소되었습니다.\n");
//장바구니 비워주기
shoppingCart.clear();
//while문 탈출해 다시 showCategory()로
break;
} else if (orderChoice == 1 || orderChoice == 2 || orderChoice == 3) {
//ORDER MENU가 아닌 MENU CATEGORY의 번호를 선택했을 경우
//각 orderChoice에 따라서 categoryChoice 재할당
if (orderChoice == 1) {
categoryChoice = 1;
} else if (orderChoice == 2) {
categoryChoice = 2;
} else if (orderChoice == 3) {
categoryChoice = 3;
}
continue; //재할당 된 categoryChoice를 가지고 다시 while문 처음으로 올라가기
} else if (orderChoice == 0) {
break; //while문 탈출해 다시 showCategory()로
} else {
throw new Exception(); //그 외의 경우 예외 발생 (orderChoice 변수 예외)
}
} else if (cartChoice == 2) {
break; //while문 탈출해 다시 showCategory()로
} else {
throw new Exception(); //그 외의 경우 예외 발생 (cartChoice 변수 예외)
}
}
break;
}
} else {
throw new Exception(); //그 외의 경우 예외 발생 (categoryChoice 변수 예외)
}
}
catch (Exception e) {
//예외처리
//예외가 처리되면 다시 while문의 처음으로
System.out.println("유효한 입력이 아닙니다.");
}
}
}
//메뉴 카테고리를 출력하는 메서드
public void showCategory() {
System.out.println("[MENU CATEGORY]");
//for문 돌면서 카테고리 출력
for (int i = 1; i <= menu.size(); i++) {
System.out.println(i + ". " + menu.get(i-1).getCategory()); //Menu 객체의 getCategory() 이용
}
System.out.println("0. 종료 | 종료\n");
}
//선택된 카테고리에 따른 메뉴들을 출력하는 메서드
public void showMenu(List<Menu> menu, int categoryChoice) {
//선택된 카테고리에 따라 메뉴 카테고리 이름 출력
if (categoryChoice == 1) {
System.out.println("[BURGERS MENU]");
} else if (categoryChoice == 2) {
System.out.println("[BEVERAGES MENU]");
} else if (categoryChoice == 3) {
System.out.println("[DESSERTS MENU]");
}
//선택된 카테고리에 따라 해당 카테고리에 속한 메뉴들을 for문 돌면서 출력
for (int i = 1; i < menu.get(categoryChoice-1).getMenuItems().size(); i++) {
//Menu를 관리하는 리스트에서 해당하는 카테고리로 인덱스 접근 -> getMenuItems()를 이용해서 MenuItem을 관리하는 리스트에 접근 ->
//for문의 i를 통해 차례대로 인덱스를 통해 접근 -> 접근한 MenuItem 리스트에 getName(), getPrice(), getDescription() 이용해서 값 출력
System.out.print(i + ". ");
System.out.printf("%-14s |",menu.get(categoryChoice-1).getMenuItems().get(i).getName());
System.out.printf(" W %-3s | ",menu.get(categoryChoice-1).getMenuItems().get(i).getPrice());
System.out.print(menu.get(categoryChoice-1).getMenuItems().get(i).getDescription()+"\n");
}
System.out.println("0. 뒤로가기\n");
}
//선택된 MenuItem의 정보를 출력하는 메서드
public void showSelectedMenu(int categoryChoice, int menuChoice) {
System.out.print("선택된 메뉴 : ");
System.out.printf("%-14s |",menu.get(categoryChoice-1).getMenuItems().get(menuChoice).getName());
System.out.printf(" W %-3s | ",menu.get(categoryChoice-1).getMenuItems().get(menuChoice).getPrice());
System.out.print(menu.get(categoryChoice-1).getMenuItems().get(menuChoice).getDescription()+"\n");
}
//장바구니에 선택된 MenuItem을 추가하는 메서드
public void addShoppingCart(MenuItem menuItem) {
shoppingCart.add(menuItem);
System.out.println(menuItem.getName() + "이 장바구니에 추가되었습니다.\n");
}
//ORDER MENU를 출력하는 메서드
public void showOrderMenu() {
System.out.println("[ORDER MENU]");
System.out.println("4. Orders | 장바구니를 확인 후 주문합니다.");
System.out.println("5. Cancel | 진행중인 주문을 취소합니다.\n");
}
//장바구니에 담긴 MenuItem을 출력 + 총 결제금액을 출력하는 메서드
public void showShoppingCartMenu(List<MenuItem> shoppingCart) {
double totalSum = 0;
System.out.println("[ORDERS]");
for (MenuItem a : shoppingCart) {
System.out.printf("%-14s |",a.getName());
System.out.printf(" W %-3s | ",a.getPrice());
System.out.print(a.getDescription()+"\n");
totalSum += a.getPrice();
}
System.out.println("[TOTAL]");
System.out.println("W " + totalSum + "\n");
}
//총 결제금액을 반환하는 메서드
public double calculateTotal(List<MenuItem> shoppingCart) {
double total = 0;
for (MenuItem a : shoppingCart) {
total += a.getPrice();
}
return total;
}
}
https://github.com/YUBIN-githubb/Kiosk.git
GitHub - YUBIN-githubb/Kiosk
Contribute to YUBIN-githubb/Kiosk development by creating an account on GitHub.
github.com
어제 level4-5 코드에서 고칠 점인 메뉴를 출력하는 부분들, 선택된 메뉴를 출력하는 부분들이 categoryChoice 변수의 조건문에 따라 계속 반복된다는 점을 이번 level6코드에서는 함수로 따로 빼서 구현하였다.
이렇게 하니 코드도 더 깔끔하게 보기 좋고 재사용성도 높아진 것 같다.
어찌저찌 level6의 첫번째 까지는 구현한 것 같지만 문제는 2번째인 것 같다. Enum, 람다, 스트림을 활용해서 코드를 개선해야 하는데 오늘 강의를 들어도 도통 이게 무엇인지 잘 감이 가지 않는다..
아마 내일 하루를 잡고 해당 개념에 대해서 공부를 우선 해야겠다. 그리고 주말에 구현 완료하는 것이 목표!
2. static은 왠만해선 쓰지 말자
나는 저번 계산기 과제에서 계산 결과를 저장하는 리스트에 static을 이용했었다. 왜냐하면 객체 간에 계산 결과들을 공유하고 싶었기 때문이다. 그런데 그거보다 더 근본적인 문제를 해결하면 그 공유 문제도 일어나지 않게 할 수 있었다.
그렇지만 난 명확한 의도를 가지고 static을 사용했기 때문에(?) 완전 틀린 사용은 아니지만,
static은 시작 시점에 항상 먼저 메모리에 올려놓고 시작하는 키워드이기 때문에 잘못하면 코드 전체내에 어마어마한 버그를 일으킬 수도 있다. 그래서 static의 개념은 알고 가되 아마 static을 사용할 일이 없을 것이며 있다 하더라도 명확한 의도를 가지고 사용해야 할 것이다.
[오늘 회고]
이제 자바문법의 기초적인 부분으로 요구사항을 보고 그에 맞는 클래스를 설계하고 클래스 안에서 적절한 필드, 생성자, 메서드까지 구현할 수 있게 된 것 같다. 그렇지만 아직 자바 고급 문법 부분인 제네릭, Enum, 람다, 스트림 부분은 잘 모른다. 이 부분을 공부해서 꼭 키오스크 과제 코드에 적용시켜보아야겠다.
오늘 우수 TIL 작성자들이 발표되어서 한번 구경 가봤다. 다들 엄청 깔끔하게 깨달았던 내용들을 쓰신 것 같다... 나도 그러고 싶은 마음 굴뚝이지만, 이제 공부 끝나면 지쳐서 요즘 TIL도 거의 일기장마냥 쓰고 있다. 앞으로 조금 더 깔끔하게? 쓰려고 하는 노력을 해야겠다는 생각도 들었다.
그리고 과제를 하면서 중간중간 발생하는 문제들에 대해서 트러블 슈팅을 작성해야한다. 또한 깃허브에도 올려야한다. 그런데 이번에는 정신이 어디다가 팔렸는지 level6까지 구현할 동안 깃헙과 연동도 안하고 push도 한번을 안했다.... 이렇게 하면 내가 코드를 뜯어고친 흔적이 보이지 않겠지.. 내 잘못이다. 앞으로는 하루에 모든 코딩 끝나고 push 한번 하는게 아닌 중간중간 코드를 고친 부분이 있으면 commit 하고 push해야겠다. 그리고 중간중간 트러블 슈팅을 작성해야하는데 아직 이걸 작성하는걸 잘 모르겠다. 하나의 글에 매일의 내용을 쭉 이어서 써야하나? 아니면 프로젝트 끝나고 기억을 되짚어 가면서 써야하나? 내일 튜터님께 팁좀 구해야겠다.
오늘은 왜 그랬는지 모르겠지만 캠프의 다른 참가자들은 어디까지 하고 있나, 세션할 때 질문들을 보면 저분들을 되게 열심히하고 잘 하시는 것 같은데 나는 이게 잘하고 있는게 맞나?라는 생각도 드는 오늘이었다. 남과 나를 자꾸 비교했었다. 그러다보니 자기혐오도 조금 심해지는 하루였다 ㅋㅋ... (오늘 한게 굉장히 적어서 양심적으로 찔려서 그랬는지도 모르겠다 ㅋㅋ) 그렇지만 그럴 때마다!
이 짤을 떠올리면서 마음을 다잡자.
'개발 회고 > TIL' 카테고리의 다른 글
[1/22] TIL - 포트, 쿠키, 세션 (0) | 2025.01.22 |
---|---|
[1/17] TIL - 키오스크 프로젝트에 Enum, Stream, IntStream 적용해보기 (1) | 2025.01.17 |
[1/15] TIL - 키오스크 프로그램 구현, 엉덩이 아프다 (1) | 2025.01.15 |
[1/14] TIL - 🌟 객체지향 연습하기 - 클래스, 상속, 가변인자 (1) | 2025.01.14 |
[1/13] TIL - 콘솔 출력 형식 지정, 계산기 코드 개선, 앞으로의 공부 다짐 😊 (0) | 2025.01.13 |