[내일배움캠프 14일차] Kiosk과제 - 필수구현 (Level 4~5)

김현정·2025년 3월 8일
0

직전 포스터에 이어서 Kiosk과제에 대한 TIL을 작성하려고 합니다.
Level 1~3은
https://velog.io/@todok0317/내일배움캠프-14일차-Kiosk과제-필수구현-Level-13
여기에서 보시면 됩니다.

Level 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을 입력
프로그램을 종료합니다.

Level 5 - 캡슐화 적용하기

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

level 4와 5는 한번에 진행하였습니다.
level 4를 구하면서 여러 난관이 있었습니다.

제가 처음 구현한 방식은

    // 속성
    private List<MenuItem> drinkList;
    private List<MenuItem> desertList;
    private List<MenuItem> hambergerList;


    // 생성자
    public Menu() {
        // 햄버거 리스트 생성 후 햄버거 메뉴 추가
        hambergerList = new ArrayList<>();
        this.hambergerList = hambergerList;
        hambergerList.add(new MenuItem("ShackBurger ", 6.9, "토마토, 양상추, 쉑소스가 토핑 된 치즈버거    "));
        hambergerList.add(new MenuItem("SmokeShack  ", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑 된 치즈버거 "));
        hambergerList.add(new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑 된 치즈버거"));
        hambergerList.add(new MenuItem("Hamburger   ", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거    "));

        // 음료수 리스트 생성 후 리스트 메뉴 추가
        drinkList = new ArrayList<>();

        // 디져트 리스트 생성 후 리스트 메뉴 추가
        desertList = new ArrayList<>();

    }

            System.out.println("[                               MAIN MENU                              ]");
            System.out.println("-----------------------------------------------------------------------");
            System.out.println("| 1. Burgers                                                           |");
            System.out.println("| 2. Drinks                                                            |");
            System.out.println("| 3. Desserts                                                          |");
            System.out.println("| 0. 종료                                                               |");
            System.out.println("-----------------------------------------------------------------------");

음료리스트, 디져트리스트, 햄버거리스트를 따로 속성을 추가해서 생성자에 햄버거 리스트에 메뉴들을 추가하고, 음료 리스트에 메뉴를 추가하는 것을 하였습니다. 이렇게 되면 kiosk에 메인메뉴를 알려줄 때 하나하나씩 입력해야하고 수정을 할 때도 직접 수정해야하는 코드의 길어짐과 유지보수가 어려워지는 단점이 생깁니다. 그렇기에 MapHash 리스트를 활용하여 메뉴리스트에 햄버거리스트, 음료리스트, 디져트리스트를 관리하는 것을 구현하였습니다.

	//속성
    private  Map<String, List<MenuItem>> menuList;
    
    //생성자
    public Menu() {
        // 햄버거 리스트 생성 후 햄버거 메뉴 추가
        menuList = new HashMap<>();
        this.menuList = menuList;

        List<MenuItem> hamburgerList = new ArrayList<>();
        hamburgerList.add( new MenuItem("ShackBurger ", 6.9, "토마토, 양상추, 쉑소스가 토핑 된 치즈버거    "));
        hamburgerList.add( new MenuItem("SmokeShack  ", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑 된 치즈버거 "));
        hamburgerList.add( new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑 된 치즈버거"));
        hamburgerList.add( new MenuItem("Hamburger   ", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거    "));
        menuList.put("Berger",hamburgerList);

        List<MenuItem> drinkList = new ArrayList<>();
        drinkList.add( new MenuItem("Sprit       ", 0.3, "청량감이 넘치는 시원한 사이다            "));
        drinkList.add( new MenuItem("Cola        ", 0.3, "청량감이 넘치는 시원한 코카콜라           "));
        drinkList.add( new MenuItem("Orenge Juice", 0.5, "오렌지 과즙이 넘치는 시원한 오렌지 쥬스    "));
        drinkList.add( new MenuItem("Tomato Juice", 0.5, "토마토 과즙이 넘치는 달달한 토마토 쥬스    "));
        menuList.put("Drink",drinkList);

        List<MenuItem> dessertList = new ArrayList<>();
        dessertList.add( new MenuItem("Icecream    ", 0.1, "우유 아이스크림                      "));
        dessertList.add( new MenuItem("Pie         ", 0.3, "고구마 파이                         "));
        menuList.put("Dessert",dessertList);
    }

MapHash 리스트 선언방식

private  Map<String, List<MenuItem>> menuList = new HashMap<>();

이렇게 메뉴리스트 안에 키 : 값을 넣어서

"햄버거" : <"ShackBurger ", 6.9, "토마토, 양상추, 쉑소스가 토핑  치즈버거">
햄버거 리스트를 생성하였습니다.

이렇게 되면 메뉴리스트를 유지보수도 편해지고 여러 메뉴에 리스트를 많이 추가할 수 있었습니다.
또한 메뉴의 카테고리로 리스트를 관리할 수 있었습니다.

    public void start() {
        int first_answer;
        int second_answer;
        int third_anwer;
        int choice;
        List<MenuItem> HamburgerList = menu.getMenuList().get("Burger");
        List<MenuItem> DrinkList = menu.getMenuList().get("Drink");
        List<MenuItem> DessertList = menu.getMenuList().get("Dessert");

Kiosk 클래스의 start함수에서

List<'MenuItem> HamburgerList = menu.getMenuList().get("Beurger"); 를 선언해줌으로써 메뉴의 메뉴리스트의 햄버거리스트를 가져올 수 있었습니다.

- List<'MenuItem>을 사용하여 제네릭 타입을 명확하게 명시해줍니다 (안그럼 List<'Odject>로 인식하기에 문제가 발생할 가능성 있음)
- menu클래스에 getMenuList()에서 "Burger" 키를 사용해 값인 리스트를 가져와 변수에 저장하는 방식.
- 즉, HambergerList에는 "Berger" 키에 해당하는 버거 메뉴 리스트,
- DrinkList에는 "Drink" 키에 해당하는 음료 메뉴 리스트,
- DessertList에는 "Dessert" 키에 해당하는 디저트 메뉴 리스트가 들어가게 됩니다.

이렇게 되면 Kiosk 클래스의 start함수에서 반복문 로직에 바로 HamburgerList를 사용할 수 있음.

            System.out.println("[                             MAIN MENU                                ]");
            System.out.println("-----------------------------------------------------------------------");

            for (int i = 0; i < menu.getMenuList().size(); i++) {
                for (String key : menu.getMenuList().keySet()) {
                    System.out.println("| " + (i + 1) + ". " + key + "                                                           |");
                    System.out.println("-----------------------------------------------------------------------");
                    i++;
                }
            }
            System.out.println("| 0. 종료                                                              |");
            System.out.println("-----------------------------------------------------------------------");

메뉴리스트의 키(버거, 음료, 디져트)를 가져와서 메뉴판을 손쉽게 만들 수 있고 (유지보수성도 높아짐)

do {
                        System.out.println("[                            BERGER MENU                               ]");
                        System.out.println("-----------------------------------------------------------------------");
                        for (int i = 0; i < HamburgerList.size(); i++) {
                            MenuItem item = menu.getMenuList().get("Burger").get(i);
                            System.out.println("| " + (i + 1) + ". " + item.getName() +
                                    "    |  W " + item.getPrice() + "  |  " + item.getDescription() + " |");
                            System.out.println("-----------------------------------------------------------------------");

                        }
                        System.out.println("| 0. 메인메뉴로 돌아가기  |  돌아가기                                         |");
                        System.out.println("-----------------------------------------------------------------------");

                        System.out.print("번호를 입력하세요 : ");
                        first_answer = sc.nextInt();
                        System.out.println("");

                        if (first_answer == 0) {
                            break;
                        }

                        if (first_answer >= 1 && first_answer <= HamburgerList.size()) {
                            MenuItem selectedItem = menu.getMenuList().get("Burger").get(first_answer - 1);
                            System.out.println("\n선택한 메뉴: " + selectedItem.getName());
                            System.out.println("가격: W " + selectedItem.getPrice());
                            System.out.println("설명: " + selectedItem.getDescription() + "\n");
                        } else {
                            System.out.println("잘못된 입력입니다. 다시 입력해주세요.");
                        }
                    } while (true);

햄버거 메뉴판을 만들 때도 변수를 가져와 할 수 있습니다.

MenuItem item = menu.getMenuList().get("Drink").get(i); 는
- MenuItem 타입의 객체 변수로 item은 변수입니다.
- menu.getMenuList() → Map<String, List<MenuItem>> 형태의 menuList를 가져옴
- .get("Drink") → menuList에서 "Drink" 키에 해당하는 음료 리스트 (List<MenuItem>)를 가져옴
- .get(i) → 음료 리스트의 i번째 요소를 가져와 item 변수에 저장
- 즉, item에는 "Drink" 카테고리의 i번째 음료 메뉴가 들어갑니다.

그리고나서 그 이후에 기능들을 구현하며 level 4,5를 마무리하였습니다.

혹시 Kiosk Main Menu MenuItem들의 클래스 코드들이 궁금하면 댓글 남겨주세요!

0개의 댓글