2023년 10월 22일

최혁·2023년 10월 23일
0
가끔 어떤 일을 하다 보면 내가 나뭇잎에 집착하고 있다는걸 느낄 때가 있다.

숲을 완성하기 위해 나무를 심어야 하는 와중에

그 나무의 잎을 보고 수종과 나무의 건강상태에 주목하고 있는걸 깨달으면

아직도 이 나쁜 버릇을 고치지 못한 고집을 어떻게 해야하나 걱정스럽다.

kiosk 만들기

예외처리

c에서는 변수를 생성하면 그 주소를 메모리에 다이렉트로 꼽아버리기 때문에
예외 처리 부분에서 신경 쓸 부분이 많았다.
가령 입력받는 변수의 자료형이 int인데 사용자가 뉴진스를 입력해버린다면
프로그램이 터져버리기 때문에

	public  static int checkInt() {
         String s;
         int i;

         while (true) {
             s = scanner.nextLine();
             try {
                 i = Integer.parseInt(s);
                 if (0 < i && i < 100) {
                     return i;
                 }
                 else
                     System.out.println("유효한 숫자를 입력해주세요.");
             } catch (NumberFormatException e) {
                 System.out.println("숫자만 입력해주세요.");
             }
         }
    }

그런 이유로 키오스크의 틀이 완성된 이후에 가장 먼저 만든 함수이다.
일전에 scanner를 사용하면서 귀찮았던 적이 있었기 때문에

double rating = Double.parseDouble(scanner.nextLine());

scanner를 대체 할 메서드를 만들어서 예외처리로 빽빽하게 둘러 넣어버릴 생각이었다.

이 덕분에 순수하게 내가 원하는 범위 내의 int값을 받아올 수 있게 되어
키오스크를 구성하는 switchcase에 잘 집어넣을 수 있었다.

다만, 이후에 다른 사람과 코드를 비교해보며 알게 되었는데,
애초에 case의 키값을 String으로 받아 넣어버리면 그럴 걱정 하나도 없다는걸 너무 늦게서야 알게 되었다.

나뭇잎을 너무 가까이 보고 있었던 탓이다.

다음에는 이런 쓰잘데기 없는 행위에 노력과 시간을 투자하지 않기로 한다.

cart 장바구니

물건을 담았으면 결제를 해야지.
근데 그 물건은 어디에 담겨있는가?

List<Menu> cart = new ArrayList<>();

전역변수로 둘까 하다가 42하던 버릇이 남아 전역변수로 두지 않았다.
다만 이것도 완성한 시점에서 깨달은건데

미션의 추가 목표를 완성시키려면 전역변수나 enum에 담아 다른 클래스들에서도 쉽게 접근 가능하게 했었다면 조금 더 효율적이고 가독성 높은 코드를 짤 수 있었을텐데 후회가 크다.

    public static int yesOrnoCart (int next, List<? extends Menu> availableItems) {

        if (next > 0 && next <= availableItems.size()) {
            Menu selectedItem = availableItems.get(next - 1);
            System.out.printf("%-5s | W %-1.1f | 재료 : ", selectedItem.name,
            	selectedItem.price / 1000);
            System.out.println("위 메뉴를 장바구니에 추가하시겠습니까?");
            System.out.println("1. 확인   2. 취소");
            int i = checkInt();
            switch (i) {
                case 1:
                    return 1;
                case 2:
                    return 2;
                default:
                    System.out.println("올바른 숫자를 입력해주세요." + '\n');
                    return yesOrnoCart(next, availableItems);
            }
        } else {
            System.out.println("올바른 숫자를 입력해 주세요.");
            return -1;
        }
    }

리스트를 만들긴 했는데 내 버리속에서 List는 아직 럭키 Array라서 메인문에 있는 List를 어떻게 해야 메서드로 넘겨 값을 가져올 수 있을까 걱정이었다.
c라면 * 포인터를 이용하면 될텐데...
는 그냥 메서드에 입력값으로 list를 꼽아버리니 얕은 복사가 되어 들어가더라.
일단 덕분에 일이 쉽게 풀렸다.

*중요*
list를 메서드로 넘기면 list의 주소가 넘어가는걸 알게 되었으니
추후에는 list를 깊은 복사 하여 넘기는 방법을 공부해오기로 하자.
언젠간 쓸 일이 있을듯 하다.

list 순회

public static int yesOrnoCart (int next, List<? extends Menu> availableItems) {

        if (next > 0 && next <= availableItems.size()) {
            Menu selectedItem = availableItems.get(next - 1);

문제가 다 해결된건 아니다.
list를 넘겨주는 방식으로 해결되었다고 하더라도
Menu 타입의 List를 어떻게 사용하는지는 잘 몰랐기 때문.
이 부분에선 솔직하게 말해 GPT-4선생의 도움을 받았다.

int next는 키오스크의 switch 내부에서 이루어지는 로직
메뉴 담기 확인, 주문하기 확인, 주문 취소하기 확인 등등 두번째 행동을 받기 위한 키이다.
지금 주목하는 부분에서는 별로 중요치 않음

List<? extends Menu> availableItems

이 부분이 문제다.

if (next > 0 && next <= availableItems.size()) {
            Menu selectedItem = availableItems.get(next - 1);

입력받는 next로 cart 내부에 있는 메뉴 번호를 가져오는 로직은 이해가 되는데
(직접 만들라고 하면 솔직히 시간이 좀 걸릴것 같다. 이해와 활용은 다른 차원의 문제.)

cartMenu를 상속받으니 extends Menu라는 이름의 avilableItem 리스트
솔직히 cart로 수정하고 싶었으나 양심적으로 두기로 했다.
를 메서드 내부에서 쓰는건 할겠다만 <? extends Menu>의 ?는 뭘까...

이것도 내일 시간이 남는다면 공부해야 할 부분으로 두자.

최종

과제는 완성되었고

switch (phaseController) 
	case 5 :
		메인 화면

부분에서 예기치 못한채로 남겨둔 버그 하나는 처리 못한 채 제출하게 되었다.

다만 이번 과제를 하면서 UML을 먼저 작성한 채 시작하자고 다짐했던 부분을 건너뛰고
그냥 곧 바로 코드를 작성하기 시작했던 부분이 추 후에 완성된 시점에서 가독성과 효율성을 바닥으로 쳐박아버리며 의도하지 않은 버그를 남겨버렸다는 부분에서 반성해야 한다는걸 기억하자.

나뭇잎은 나중에 보자.
숲을 완성한 후 감상해도 늦지 않으니.

0개의 댓글