코딩/sparta TIL

CH 2 : 키오스크 과제

americanoallday 2025. 3. 10. 16:41

개발 프로세스 가이드

더보기
더보기

0단계 : 개발환경 세팅

  1. IntelliJ IDEA 설치 및 실행
  2. 새 Java 프로젝트 생성
    • IntelliJ IDEA를 열고, Welcome Screen에서 New Project를 클릭합니다.
      • 기존 프로젝트가 열려 있다면, File 메뉴에서 New -> Project...를 선택합니다.
    • 프로젝트 타입 선택 : 왼쪽 사이드바에서 Java를 선택합니다.
    • JDK 선택: Project SDK 드롭다운에서 사용할 JDK 버전을 선택합니다. JDK가 설치되어 있지 않다면, Add SDK를 클릭하여 설치된 JDK 경로를 지정합니다. 17버전 지정
    • 프로젝트 템플릿 선택: 기본적으로 Create project from template은 선택하지 않고 진행합니다.
    • 프로젝트 이름 및 위치 설정: Project name 필드에 프로젝트 이름을 입력합니다. (예: KioskProject)
      • Project location 필드에서 프로젝트를 저장할 위치를 지정합니다.
    • Finish 버튼을 클릭하여 프로젝트를 생성합니다.
  3. 패키지 및 클래스 추가
    • 패키지 생성:
      • 프로젝트가 생성되면, src 폴더를 우클릭하고 New -> Package를 선택합니다.
      • 패키지 이름을 입력합니다. (예: com.example.kiosk).
    • 클래스 생성:
      • 생성한 패키지를 우클릭하고, New -> Java Class를 선택합니다.
        • IntelliJ IDEA에서 생성된 Main.java 파일을 열고, 기본 코드를 입력합니다.
          • 예시
          • package com.example.kiosk; public class Main{ public static void main(String[] args) { System.out.println("Hello, Kiosk!"); } }
      • 클래스 이름을 입력합니다. (예: Main) 이후, Enter를 눌러 클래스 파일을 생성합니다.
  4. 기본 코드 작성
    • 코드를 작성한 후, 파일을 저장합니다.
  5. 프로젝트 실행
    • 실행 구성 설정:
      • 상단 메뉴에서 Run -> Edit Configurations...를 선택합니다.
        • 버튼을 클릭하고 Application을 선택하여 새로운 실행 구성을 추가합니다.
      • Main class 필드에 com.example.kiosk.Main를 입력하거나, ... 버튼을 클릭하여 클래스를 선택합니다.
      • 설정이 완료되면 Apply를 클릭하고 OK를 클릭합니다.
    • 프로젝트 실행:
      • 상단의 Run 버튼(녹색 화살표)을 클릭하거나, Shift + F10을 눌러 프로그램을 실행합니다.
      • 콘솔 창에서 "아래 과제의 출력 결과물"이 출력되는 것을 확인할 수 있습니다.

이렇게 IntelliJ IDEA를 사용하여 새 Java 프로젝트를 생성하고 기본 클래스를 작성할 수 있습니다. 이후 단계에서는 요구사항 정의, 설계, 구현 등을 진행하면 됩니다.

 

1단계 : 요구사항 정의 및 설계

  • 이미 요구사항이 주어졌다면, 구현을 위해 어떤 요구사항이 있는지 숙지해야합니다.
  1. 요구사항 정의
    • 어떤 키오스크 기능이 필요한지 명확히 합니다.
    • 예를 들어, 기본적인 메뉴 선택 “입력”, “출력”, “각 메뉴 관리”, “전체 메뉴 관리” 등
    • 사용자 인터페이스 방식 결정 : 콘솔 기반인지, GUI(그래픽 사용자 인터페이스) 기반인지
      • 우리는 콘솔 기반입니다 🙂
    • 예외 처리 : 입력값으로 허용한 값 이외의 값이 입력되었을 때와 같은 오류를 어떻게 처리할지 결정
  2. 설계
    • 클래스 다이어그램 : 키오스크에 필요한 클래스를 설계합니다.
      • 예를 들어, MenuItem, Kiosk 등이 될 수 있습니다.
    • 기능 분해 : 주요 기능을 메소드로 분리합니다.
      • 예를 들어, getter(), setter() 등
    • 데이터 흐름 설계 : 데이터가 클래스 간에 어떻게 흐를지를 결정합니다.
      • 입력, 처리, 출력의 흐름을 이해합니다.

 

필수 기능 가이드

더보기
더보기

클래스 정의

  • Main : 시작 지점이 되는 클래스, public static void main(String[] args)
  • MenuItem: 세부 메뉴 속성 가지는 클래스
    • 햄버거의 이름, 가격설명
      • 예시: ShackBurger, 6.9, 토마토, 양상추, 쉑소스가 토핑된 치즈버거
      • new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거")
    • 햄버거의 이름, 가격설명
      • 예시: ShackBurger, 6.9, 토마토, 양상추, 쉑소스가 토핑된 치즈버거
      • new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거")토
  • Kiosk: 프로그램 순서 및 흐름 제어를 담당하는 클래스
  • Menu: MenuItem 클래스를 관리하는 클래스
    • 예시 : 버거 메뉴, 음료 메뉴 등 각 카테고리 내에 여러 MenuItem을 포함합니다.

클래스 정의

  • Main : 시작 지점이 되는 클래스, public static void main(String[] args)
  • MenuItem: 세부 메뉴 속성 가지는 클래스
    • 햄버거의 이름, 가격설명
      • 예시: ShackBurger, 6.9, 토마토, 양상추, 쉑소스가 토핑된 치즈버거
      • new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거")
    • 햄버거의 이름, 가격설명
      • 예시: ShackBurger, 6.9, 토마토, 양상추, 쉑소스가 토핑된 치즈버거
      • new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거")토
  • Kiosk: 프로그램 순서 및 흐름 제어를 담당하는 클래스
  • Menu: MenuItem 클래스를 관리하는 클래스
    • 예시 : 버거 메뉴, 음료 메뉴 등 각 카테고리 내에 여러 MenuItem을 포함합니다.
[ SHAKESHACK MENU ]
1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거
3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거
4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
0. 종료      | 종료
0 <- // 0을 입력

프로그램을 종료합니다.

 

Lv 2. 객체 지향 설계를 적용해 햄버거 메뉴를 클래스로 관리하기

  • [ ] 요구사항이 가지는 의도
    • [ ] 객체 지향 개념을 학습하고, 데이터를 구조적으로 관리하며 프로그램을 설계하는 방법을 익힙니다.
    • [ ] 햄버거 메뉴를 MenuItem 클래스와 List를 통해 관리합니다.

  • [ ] MenuItem 클래스 생성하기
    • [ ] 설명 : 개별 음식 항목을 관리하는 클래스입니다. 현재는 햄버거만 관리합니다.
    • [ ] 클래스는 이름, 가격, 설명 필드를 갖습니다.
  • [ ] main 함수에서 MenuItem 클래스를 활용하여 햄버거 메뉴를 출력합니다.
    • [ ] MenuItem 객체 생성을 통해 이름, 가격, 설명을 세팅합니다.
      • [ ] 키워드: new
    • [ ] List를 선언하여 여러 MenuItem을 추가합니다.
      • [ ] List<MenuItem> menuItems = new ArrayList<>();
    • [ ] 반복문을 활용해 menuItems를 탐색하면서 하나씩 접근합니다.
  • [ ] 구조 예시
public static void main(String[] args) {
		// List 선언 및 초기화
		// add 함수를 통해 new MenuItem(이름, 가격, 설명) List에 삽입
		
		// Scanner 선언
		
		// 반복문을 활용해 List 안에 있는 MenuItem을 하나씩 출력
		// 숫자를 입력 받기
		// 입력된 숫자에 따른 처리
			// 프로그램을 종료
			// 선택한 메뉴 : 이름, 가격, 설명
}

 

Lv 3. 객체 지향 설계를 적용해 순서 제어를 클래스로 관리하기

  • [ ] 요구사항이 가지는 의도
    • [ ] 객체 지향 개념을 학습하고, 데이터를 구조적으로 관리하며 프로그램을 설계하는 방법을 익힙니다.
    • [ ] main 함수에서 관리하던 전체 순서 제어를 Kiosk 클래스를 통해 관리합니다.
  • [ ] Kiosk 클래스 생성하기
    • [ ] 설명: 키오스크 프로그램의 메뉴를 관리하고 사용자 입력을 처리하는 클래스입니다.
    • [ ] MenuItem을 관리하는 리스트가 필드로 존재합니다.
    • [ ] main 함수에서 관리하던 입력과 반복문 로직은 이제 start 함수를 만들어 관리합니다.
    • [ ] List<MenuItem> menuItems 는 Kiosk 클래스 생성자를 통해 값을 할당합니다.
      • [ ] Kiosk 객체를 생성하고 사용하는 main 함수에서 객체를 생성할 때 값을 넘겨줍니다.
  • [ ] 요구사항에 부합하는지 검토
    • [ ] 키오스크 프로그램을 시작하는 메서드가 구현되어야 합니다.
      • [ ] 콘솔에 햄버거 메뉴를 출력합니다.
      • [ ] 사용자의 입력을 받아 메뉴를 선택하거나 프로그램을 종료합니다.
      • [ ] 유효하지 않은 입력에 대해 오류 메시지를 출력합니다.
      • [ ] 0을 입력하면 프로그램이 ‘뒤로가기’되거나 ‘종료’됩니다.

Lv 4. 객체 지향 설계를 적용해 음식 메뉴와 주문 내역을 클래스 기반으로 관리하기

  • [ ] Menu 클래스 생성하기
    • [ ] 설명 : MenuItem 클래스를 관리하는 클래스입니다. 예를 들어, 버거 메뉴, 음료 메뉴 등 각 카테고리 내에 여러 MenuItem을 포함합니다.
    • [ ] List<MenuItem> 은 Kiosk 클래스가 관리하기에 적절하지 않으므로 Menu 클래스가 관리하도록 변경합니다.
    • [ ] 여러 버거들을 포함하는 상위 개념 ‘버거’ 같은 카테고리 이름 필드를 갖습니다.
    • [ ] 메뉴 카테고리 이름을 반환하는 메서드가 구현되어야 합니다.
  • [ ] 구조 예시
public static void main(String[] args) {
		// Menu 객체 생성하면서 카테고리 이름 설정
		// Menu 클래스 내 있는 List<MenuItem> 에 MenuItem 객체 생성하면서 삽입
		
		// Kiosk 객체 생성
		// Kiosk 내 시작하는 함수 호출
}

public class Kiosk {

		start() {
			// 스캐너 선언
			// 반복문 시작
			
			// List와 Menu 클래스 활용하여 상위 카테고리 메뉴 출력
			
			// 숫자 입력 받기
			
			// 입력 받은 숫자가 올바르다면 인덱스로 활용하여 List에 접근하기
				// List<Menu>에 인덱스로 접근하면 Menu만 추출할 수 있겠죠?
			
			// Menu가 가진 List<MenuItem>을 반복문을 활용하여 햄버거 메뉴 출력
			
			// 숫자 입력 받기
			// 입력 받은 숫자가 올바르다면 인덱스로 활용해서 Menu가 가지고 있는 List<MenuItem>에 접근하기
				// menu.getMenuItems().get(i); 같은 형식으로 하나씩 들어가서 얻어와야 합니다.
		}

}

public class Menu {

		// 카테고리 이름 필드 추가
		// MenuItem 클래스를 List로 관리
		
		// List에 포함된 MenuItem을 순차적으로 보여주는 함수
		// List를 리턴하는 함수
		
		// 구조에 맞게 함수를 선언해놓고 가져다 사용하세요.
}

public class MenuItem {
		// 이름, 가격, 설명 필드 선언하여 관리
		
		// 구조에 맞게 함수를 선언해놓고 가져다 사용하세요.
}

 

Lv4를 구현하면 터미널에 이렇게 보여집니다.

[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
1 <- // 1을 입력

[ BURGERS MENU ]
1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거
3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거
4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
0. 뒤로가기
2 <- // 2를 입력
선택한 메뉴: SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
0 <- // 0을 입력
프로그램을 종료합니다.

 

Lv 5. 캡슐화 적용하기

  • [ ] MenuItem, Menu 그리고 Kiosk 클래스의 필드에 직접 접근하지 못하도록 설정합니다.
  • [ ] Getter와 Setter 메서드를 사용해 데이터를 관리합니다.

 

도전 기능 가이드

더보기
더보기

Lv 1. 장바구니 및 구매하기 기능을 추가하기

  • [ ] 요구사항이 가지는 의도
    • [ ] 의도: 클래스 간 연계를 통해 객체 지향 프로그래밍의 기본적인 설계를 익히고, 사용자 입력에 따른 프로그램 흐름 제어와 상태 관리를 학습
    • [ ] 목표
      • [ ] 클래스 간 역할 분리를 이해하고, 적절히 협력하는 객체를 설계
      • [ ] 프로그램 상태 변경 및 데이터 저장을 연습
      • [ ] 사용자 입력에 따른 예외 처리와 조건 분기를 연습

  • [ ] 장바구니 생성 및 관리 기능
    • [ ] 사용자가 선택한 메뉴를 장바구니에 추가할 수 있는 기능을 제공합니다.
    • [ ] 장바구니는 메뉴명, 수량, 가격 정보를 저장하며, 항목을 동적으로 추가 및 조회할 수 있어야 합니다.
    • [ ] 사용자가 잘못된 선택을 했을 경우 예외를 처리합니다(예: 유효하지 않은 메뉴 번호 입력)
  • [ ] 장바구니 출력 및 금액 계산
    • [ ] 사용자가 결제를 시도하기 전에, 장바구니에 담긴 모든 메뉴와 총 금액을 출력합니다.
    • [ ] 출력 예시
      • [ ] 각 메뉴의 이름, 가격, 수량
      • [ ] 총 금액 합계
  • [ ] 장바구니 담기 기능
    • [ ] 메뉴를 클릭하면 장바구니에 추가할 지 물어보고, 입력값에 따라 “추가”, “취소” 처리합니다.
      • [ ] 메뉴는 한 번에 1개만 담을 수 있습니다.
    • [ ] 장바구니에 담은 목록을 출력합니다.
  • [ ] 주문 기능
    • [ ] 장바구니에 담긴 모든 항목을 출력합니다.
    • [ ] 합산하여 총 금액을 계산하고, “주문하기”를 누르면 장바구니를 초기화합니다.
[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
1 <- // 1을 입력

[ BURGERS MENU ]
1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거
3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거
4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
0. 뒤로가기
2 <- // 2를 입력
선택한 메뉴: SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

// 2번을 누르면 나오는 메뉴입니다.
"SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"
위 메뉴를 장바구니에 추가하시겠습니까?
1. 확인        2. 취소
1 <-

// 1번을 누르면 나오는 메뉴입니다.
SmokeShack 이 장바구니에 추가되었습니다.

// 장바구니에 물건이 들어 있으면 아래와 같이 [ ORDER MENU ] 가 추가로 출력됩니다.
// 만약에 장바구니에 물건이 들어 있지 않다면 [ ORDER MENU ] 가 출력되지 않습니다. 
// 미출력일 때 4,5 번을 누르면 예외를 던저줘야 합니다.
아래 메뉴판을 보시고 메뉴를 골라 입력해주세요.

[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료

[ ORDER MENU ]
4. Orders       | 장바구니를 확인 후 주문합니다.
5. Cancel       | 진행중인 주문을 취소합니다.
4 <- // 4를 입력

// 4번을 누르면 나오는 메뉴입니다.
아래와 같이 주문 하시겠습니까?

[ Orders ]
SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

[ Total ]
W 8.9

1. 주문      2. 메뉴판
1 <-

// 1번을 누르면 나오는 메뉴입니다.
주문이 완료되었습니다. 금액은 W 8.9 입니다.

 

Lv 2. Enum, 람다 & 스트림을 활용한 주문 및 장바구니 관리

  • [ ] 요구사항이 가지는 의도
    • [ ] 의도 : 고급 자바 기능을 활용해 프로그램의 효율성과 코드의 가독성을 개선하는 것을 목표로 합니다.
    • [ ] 목적
      • [ ] Enum을 통해 상수를 안전하게 관리하고, 프로그램 구조를 간결하게
      • [ ] 제네릭을 활용하여 데이터 유연성을 높이고, 재사용 가능한 코드를 설계
      • [ ] 스트림 API를 사용하여 데이터를 필터링하고, 간결한 코드로 동작을 구현

  • [ ] Enum을 활용한 사용자 유형별 할인율 관리하기
    • [ ] 사용자 유형의 Enum 정의 및 각 사용자 유형에 따른 할인율 적용
      • [ ] 예시 : 군인, 학생, 일반인
    • [ ] 주문 시, 사용자 유형에 맞는 할인율 적용해 총 금액 계산
  • [ ] 람다 & 스트림을 활용한 장바구니 조회 기능
    • [ ] 기존에 생성한 Menu의 MenuItem을 조회 할 때 스트림을 사용하여 출력하도록 수정
    • [ ] 기존 장바구니에서 특정 메뉴 빼기 기능을 통한 스트림 활용
      • [ ] 예시 : 장바구니에 SmokeShack 가 들어 있다면, stream.filter를 활용하여 특정 메뉴 이름을 가진 메뉴 장바구니에서 제거
  • [ ] 구조 예시
[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료
1 <- // 1을 입력

[ BURGERS MENU ]
1. ShackBurger   | W 6.9 | 토마토, 양상추, 쉑소스가 토핑된 치즈버거
2. SmokeShack    | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거
3. Cheeseburger  | W 6.9 | 포테이토 번과 비프패티, 치즈가 토핑된 치즈버거
4. Hamburger     | W 5.4 | 비프패티를 기반으로 야채가 들어간 기본버거
0. 뒤로가기
2 <- // 2를 입력
선택한 메뉴: SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

// 2번을 누르면 나오는 메뉴입니다.
"SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"
위 메뉴를 장바구니에 추가하시겠습니까?
1. 확인        2. 취소
1 <-

// 1번을 누르면 나오는 메뉴입니다.
SmokeShack 이 장바구니에 추가되었습니다.

// 장바구니에 물건이 들어 있으면 아래와 같이 [ ORDER MENU ] 가 추가로 출력됩니다.
// 만약에 장바구니에 물건이 들어 있지 않다면 [ ORDER MENU ] 가 출력되지 않습니다. 
// 미출력일 때 4,5 번을 누르면 예외를 던저줘야 합니다.
아래 메뉴판을 보시고 메뉴를 골라 입력해주세요.

[ MAIN MENU ]
1. Burgers
2. Drinks
3. Desserts
0. 종료      | 종료

[ ORDER MENU ]
4. Orders       | 장바구니를 확인 후 주문합니다.
5. Cancel       | 진행중인 주문을 취소합니다.
4 <- // 4를 입력

// 4번을 누르면 나오는 메뉴입니다.
아래와 같이 주문 하시겠습니까?

[ Orders ]
SmokeShack | W 8.9 | 베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거

[ Total ]
W 8.9

1. 주문      2. 메뉴판
1 <-

// 1번을 누르면 할인 정보를 제공해줍니다.
할인 정보를 입력해주세요.
1. 국가유공자 : 10% 
2. 군인     :  5%
3. 학생     :  3%
4. 일반     :  0%
4 <-

// 4번을 누르면 나오는 메뉴입니다.
주문이 완료되었습니다. 금액은 W 8.9 입니다.

 

Goal : 제출 일정 및 트러블 슈팅하는 법

더보기
더보기

최종 제출

  • 기한 : 03/14(금) 14:00
  • 제출해야 할 것
    1. 과제
      1. Github 링크 (Public)
      2. 트러블슈팅을 작성한 TIL
      3. 어디까지 구현했는지
      4. 어떤 부분을 고민했는지, 어려웠던 부분은 어디였는지
        1. 해당 부분을 작성하시면 피드백 간, 튜터님께서 확인 후 피드백 해주실 예정입니다.
    2. 제출 링크 https://nbcamp.spartacodingclub.kr/mypage/assignments

 

트러블 슈팅

🐧 1. 출력물이 일정 간격으로 이쁘게 보이고 싶어서 알아본 결과 형식지정자라는 기능을 알아냄

https://americanoallday.tistory.com/39

 

TIL 15 : 형식 지정자, stream sorted

형식 지정자(Format Specifier)printf() 또는 String.format()을 사용할 때, 출력할 값의 형태를 지정하는 기호. 형식 지정자의 기본 구조%[플래그][너비][.정밀도]변환문자 • % → 형식 지정자가 시작됨을

americanoallday.tistory.com

 

👾 2. 무한루프에서 숫자 입력이 아닐 경우 예외처리 하는 방법으로 

throw를 아래처럼 썼는데 무조건 예외가 발생하고 있어서, 해결 방법으로 try-catch문 사용

 

수정 전 코드

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Kiosk kiosk = new Kiosk();

        System.out.println("[ SHAKESHACK MENU ]");
        kiosk.start();

        int num=10;
        do{
            num = sc.nextInt();
            throw new RuntimeException("숫자를 입력해주세요");
        }while(num!=0);
    }
}

 

수정 후 코드

int num = 10;
do {
    System.out.print("메뉴를 선택하세요 (0 입력 시 종료): ");
    
    try {
        num = sc.nextInt(); // 숫자 입력받기
    } catch (Exception e) {
        System.out.println("잘못된 입력입니다. 숫자를 입력해주세요.");
        sc.nextLine(); // 버퍼 비우기
        continue; // 다시 입력받도록 루프 반복
    }
    
} while (num != 0);
System.out.println("프로그램 종료");

 

 

🐧 3. 콘솔창에 따옴표 나오는 방법 몰라서 알아냄.

-> 이스케이프 문자 \"를 사용해서 따옴표 출력 해결

 

👾 4. start() 메소드에서 num변수 초기화 후 runtimeexception 발생

- 원인 : cart list가 null 상태여서 ArrayList<>() 초기화로 해결

 

문제 코드

public class Kiosk {

    private List<MenuItem> cart;

    public Kiosk() {
    }

    public void start() {
        // 스캐너 선언
        Scanner sc = new Scanner(System.in);
        Menu menu = new Menu();

        // 반복문 시작
        int num = 123;
        do {
            try {
                // List와 Menu 클래스 활용하여 상위 카테고리 메뉴 출력
                // 장바구니에 물건이 들어 있으면 아래와 같이 [ ORDER MENU ] 가 추가로 출력됩니다.
                // 만약에 장바구니에 물건이 들어 있지 않다면 [ ORDER MENU ] 가 출력되지 않습니다.
                // 미출력일 때 4,5 번을 누르면 예외를 던저줘야 합니다.
                if(cart.isEmpty()){
                    menu.displayCategory(0);
                }else{
                    System.out.println("아래 메뉴판을 보시고 메뉴를 골라 입력해주세요.");
                    menu.displayCategory(1);
                }
                num = sc.nextInt();
                System.out.println();

                if (num == 1) {
                    // Menu가 가진 List<MenuItem>을 반복문을 활용하여 햄버거 메뉴 출력
                    menu.displayMenuItems();
                    num = sc.nextInt(); // 숫자 입력 받기
                    if (num != 0) {
                        // 입력 받은 숫자가 올바르다면 인덱스로 활용하여 List에 접근하기
                        // menu.getMenuItems().get(i); 같은 형식으로 하나씩 들어가서 얻어와야 합니다.
                        menu.selectMenu(menu.getMenuItem().get(num - 1));
                        System.out.println();
                        addCart(menu.getMenuItem().get(num-1));
                    }
                }else if(num==4){
                    orderMenu(menu.getMenuItem().get(num-1));
                }

            } catch (RuntimeException e) { // 유효하지 않은 입력에 대한 예외처리
                System.out.println("!!!숫자를 입력해주세요!!!");
                System.out.println();
                sc.nextLine(); // 버퍼 비우기
                continue;
            }
        } while (num != 0);
    }

    public void addCart(MenuItem item) {

        System.out.printf("\"%-15s | W %-4.1f | %s\"", item.getName(), item.getPrice(), item.getDescription());
        System.out.println("위 메뉴를 장바구니에 추가하시겠습니까?");
        System.out.printf("%-15s %-15s", "1. 확인", "2. 취소");

        Scanner sc = new Scanner(System.in);
        int choice = sc.nextInt();

        try {
            if (choice == 1) {
                cart.add(item);
                System.out.printf("%s %s", item.getName(), "이 장바구니에 추가되었습니다.");
                System.out.println();
            }
        } catch (RuntimeException ex) {
            System.out.println("\"1 또는 2를 입력해주세요\"");
            System.out.println();
            sc.nextLine(); // 버퍼 비우기
        }
    }

    public void orderMenu(MenuItem item){
        System.out.println("아래와 같이 주문 하시겠습니까?");
        System.out.println();
        System.out.println("[ Orders ]");
        System.out.printf("\"%-15s | W %-4.1f | %s\"\n", item.getName(), item.getPrice(), item.getDescription());
        System.out.println();
        System.out.println("[ Total ]");

        int total = 0;
        for(MenuItem i : this.cart){
            total += i.getPrice();
        }
        System.out.printf("W %-4.1f", total);
        System.out.printf("%-15s %-15s", "1. 주문", "2. 메뉴판");
        Scanner sc = new Scanner(System.in);

        int choice = sc.nextInt();
        try{
            if(choice==1){
                System.out.printf("%s W %-4.1f %s\n", "주문이 완료되었습니다. 금액은",total,"입니다.");
            }
        } catch (RuntimeException e) {
            System.out.println("\"1 또는 2를 입력해주세요\"");
            System.out.println();
            sc.nextLine(); // 버퍼 비우기
        }
    }

}

 

 

🐧 5. cart에 넣은 순서대로 index 표기 방법으로 배열을 만들어서 해당 배열 값을 증가시켜주는 방식으로 해결함

해당 과정에서, 람다식 내부에 지역변수가 변경이 안되는 것을 알아냄.

  public void cancelItem(){
        Scanner sc = new Scanner(System.in);
        int[] index = {1};
        // int index = 1 이 안되는 이유
        // 람다식 내부에서는 지역 변수를 변경 할 수 없음.
        System.out.println("취소할 주문을 선택해 주세요. (취소 : enter)");
        System.out.println("[ Cart ]");
        cart.stream().forEach(item -> System.out.printf("%d. %-15s | W %-4.1f | %s\n", index[0]++, item.getName(), item.getPrice(), item.getDescription()));

        index[0] = 1;
        String input = sc.nextLine();
        if(!input.isEmpty()){
            cart.remove((Integer.parseInt(input)-1));
            System.out.println("[ Cart ]");
            cart.stream().forEach(item -> System.out.printf("%d. %-15s | W %-4.1f | %s\n", index[0]++ , item.getName(), item.getPrice(), item.getDescription()));
        }
    }