Troubleshooting: 무엇이 문제였는가?/본캠프 2주 차: 키오스크 만들기

3단계: "아이고, 믿는 sout에 발등 찍힌다더니!"

writingforever162 2024. 11. 25. 19:31

[문제]

package com.example.kiosk.level3;

import java.util.*;

public class Kiosk {
    Scanner sc = new Scanner(System.in);
    List<MenuItem> menuItems;

    public Kiosk(List<MenuItem> menuItems) {
        this.menuItems = menuItems;
    }

    public void start() {
        int index;
        for (index = 0; index < this.menuItems.size(); index++) {
            this.menuItems.get(index).getMenuInfo(index + 1);
        }
        System.out.println("0. 종료           | 종료");

        while (true) {
            System.out.println();
            System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
            System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
            index = sc.nextInt();

            if (index >= 5 || index == 0) {
                System.out.println("메뉴 번호 외에 다른 숫자를 입력했습니다. 프로그램을 종료합니다.");
                break;
            } else {
                System.out.println();
                System.out.println(menuItems.get(index - 1).getEachItem());
                // [문제] 위 코드에서 오류 표시가 떴다!
            }
        }
    }
}

도대체 뭘 잘못 입력했나, 빨간 전구를 눌러 확인해도 이렇다 할 해결법을 제시하지 못했다. 빨간 줄이 그어진 코드를 뚫어져라 한참 째려본 뒤에야 원인을 찾을 수 있었다.

 

[원인]

package com.example.kiosk.level3;
// Kiosk 클래스
import java.util.*;

public class Kiosk {
    Scanner sc = new Scanner(System.in);
    List<MenuItem> menuItems;

    public Kiosk(List<MenuItem> menuItems) {
        this.menuItems = menuItems;
    }

    public void start() {
        int index;
        for (index = 0; index < this.menuItems.size(); index++) {
            this.menuItems.get(index).getMenuInfo(index + 1);
        }
        System.out.println("0. 종료           | 종료");

        while (true) {
            System.out.println();
            System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
            System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
            index = sc.nextInt();

            if (index >= 5 || index == 0) {
                System.out.println("메뉴 번호 외에 다른 숫자를 입력했습니다. 프로그램을 종료합니다.");
                break;
            } else {
                System.out.println();
                System.out.println(menuItems.get(index - 1).getEachItem());
                // [오답] System.out.println(menuItems.get(index - 1).getEachItem());
                // [정답] menuItems.get(index - 1).getEachItem();
            }
        }
    }
}

원인은 getEachItem() 메서드에 이미 sout, 일명 System.out.println() 메서드를 작성했다는 데에 있었다. 이미 출력 기능까지 포함한 메서드를 출력하겠다고 System.out.println()로 다시 한번 감쌌으니, 컴퓨터가 혼란스러워할 만했다.

package com.example.kiosk.level3;
// MenuItem 클래스
public class MenuItem {

    private String name;
    private double price;
    private String description;

    public MenuItem(String name, double price, String description) {
        this.name = name;
        this.price = price;
        this.description = description;
    }

    public void getMenuInfo(int menuNum) {
        // [1] 각 멤버변수 수정이 쉽도록 print() 사용
        System.out.print(menuNum + ". " + this.name);
        System.out.print("      | W " + this.price);
        System.out.println(" | " + this.description);
    }

    public void getEachItem() {
        System.out.println(this.name + " 1개가 선택되었습니다.");
        System.out.println("가격은 " + (int)(this.price * 1000) + "원입니다.");
        // [설명] MenuItem 클래스의 getEachItem() 메서드에서 이미 썼는데,
        //       Kiosk 클래스로 호출 후 또 한 번 sout로 감싸서 문제가 됐다.
    }
}

어이없는 실수라는 점과는 별개로, MenuItem 클래스의 getEachItem() 메서드를 어떻게 작성했는지 기억하는 데 오래 걸려서 원인을 금방 찾지 못했다. 이때 직감했다. 이 실수를 기록해 두지 않으면, 앞으로 수많은 클래스 안에 수많은 메서드를 작성하면서 몇 번이고 반복할지 모른다고. 

 

[해결]

package com.example.kiosk.level3;
// Kiosk 클래스
import java.util.*;

public class Kiosk {
    Scanner sc = new Scanner(System.in);
    List<MenuItem> menuItems;

    public Kiosk(List<MenuItem> menuItems) {
        this.menuItems = menuItems;
    }

    public void start() {
        int index;
        for (index = 0; index < this.menuItems.size(); index++) {
            this.menuItems.get(index).getMenuInfo(index + 1);
        }
        System.out.println("0. 종료           | 종료");

        while (true) {
            System.out.println();
            System.out.println("메뉴판에서 원하는 햄버거 번호를 입력해 주세요.");
            System.out.print("만약 종료를 원하신다면 0을 입력해 주세요: ");
            index = sc.nextInt();

            if (index >= 5 || index == 0) {
                System.out.println("메뉴 번호 외에 다른 숫자를 입력했습니다. 프로그램을 종료합니다.");
                break;
            } else {
                System.out.println();
                menuItems.get(index - 1).getEachItem();
                // [수정 전] System.out.println(menuItems.get(index - 1).getEachItem());
                // [수정 후] menuItems.get(index - 1).getEachItem();
            }
        }
    }
}

앞으로는 sout만 입력하여 System.out.println() 메서드를 자동 완성하기 전에 한 번 더 생각하는 습관을 다져야겠다. 정말 믿는 도끼에 발등이라도 찍힌 양 '아이고' 곡소리가 절로 나왔다.