TIL

CH2 키오스크 과제 TIL

phonebee 2025. 1. 19. 21:28

▶ Lv 1. 기본적인 키오스크를 프로그래밍해보자

▷ 문제 풀이 시 요구사항

● Scanner를 사용하여 햄버거 메뉴를 출력

● 입력받은 숫자에 따라 다른 로직 실행

● 반복문을 이용해서 특정 번호가 입력되면 프로그램을 종료

 

▷ 코드 제작 과정

- 리스트를 사용하여 정보를 저장할 수 있지만, Lv1에서 사용하기엔 아니라고 판단하여 2차원 배열을 통해서 햄버거 매뉴 정보를 저장했다.

//2차원 배열을 통한 햄버거 메뉴 저장
String[][] menuItem={
        {"ShackBurger", "6.9", "토마토, 양상추, 쉑소스가 토핑된 치즈버거"},
        {"SmokeShack", "8.9", "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"},
        {"Cheeseburger", "6.9", "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"},
        {"Hamburger", "5.4", "비프패티를 기반으로 야채가 들어간 기본버거"}
};

 

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

▷ 문제 풀이 시 요구사항

● 햄버거 메뉴를 MenuItem 클래스와 List를 통해서 관리해야한다.

● 클래스는 이름, 가격, 설명 필드를 갖는다.

● Main 클래스에서 MenuItem 클래스를 활용하여 햄버거 메뉴를 출력해야한다.

 

▷ 코드 제작 과정

- 리스트를 사용해서 햄버거 메뉴를 관리해야한다고 명시가 되어있기 때문에 ArrayList를 사용했다.

→ 왜 ArrayList를 사용했는가?

: 배열과 다르게 ArrayList는 따로 크기가 명시되어 있지 않으며 값을 추가할 때마다 인덱스 번호가 주어져 값을 꺼내기 쉽기 때문에 사용했다.

- MenuItem 클래스에는 이름, 가격, 설명을 저장하는 필드를 생성하고 필드에 값을 저장하는 생성자를 생성했다.

public class MenuItem {
    //MeunItem 필드
    String foodName;
    double foodPrice;
    String foodInfo;

    /*매개변수를 지닌 MenuItem 생성자
    생성자를 호출하여 각 MenuItem 필드에 값을 저장한다.*/
    public MenuItem(String foodName, double foodPrice, String foodInfo) {
        this.foodName = foodName;
        this.foodPrice = foodPrice;
        this.foodInfo = foodInfo;
    }
}

 

▷ 트러블 슈팅

● 발단

햄버거의 매뉴 정보를 저장하기 위해 리스트를 제작하던 중 나타나게 되었다.

● 문제

햄버거 메뉴의 정보는 이름, 가격, 정보로 총 3가지를 저장해야하는데 하나의 값으로 저장하는 방법이 떠오르지 않았다.

● 해결 과정

리스트에 값을 저장할 때는 add() 메서드를 사용하여 저장하는데, 객체를 통해서도 저장할 수 있다. 즉, Main 클래스에서 MenuItem 클래스의 객체를 생성하고, 생성자를 통해서 값을 저장한다.

이런 식으로 저장된다면, 리스트의 한 인덱스 안에는 MenuItem 객체 하나가 들어가게 된다.

이런 식으로 주어진 햄버거 메뉴를 리스트 안에 저장하여 향상된 for문을 통해서 출력할 수 있도록 제작했다.

//menuItem 리스트에 MenuItem 생성자를 통해서 값을 저장
menuItems.add(new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거"));
menuItems.add(new MenuItem("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"));
menuItems.add(new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"));
menuItems.add(new MenuItem("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거"));
for (MenuItem menuItem : menuItems) {
    System.out.println(index+". "+menuItem.foodName+" | W "+menuItem.foodPrice+" | "+menuItem.foodInfo);
    index++;
}

 

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

▷ 문제 풀이 시 요구사항

● Main 클래스에서 출력하는 순서를 Kiosk 클래스를 통해 관리해야한다.

● Kiosk 클래스 안에는 MenuItem을 관리하는 리스트가 필드로 존재한다.

● 반복문 로직들은 Kiosk 클래스 안에 Start 메서드로 제작한다.

● 콘솔에 햄버거 메뉴를 출력해야한다.

● 사용자의 입력을 받아 메뉴를 선택하거나 프로그램이 종료되어야 한다.

● 유효하지 않은 입력에 대해 오류 메시지를 출력해야한다.

● 0을 입력하면 프로그램이 뒤로가기가 되거나 종료되어야한다.

 

▷ 코드 제작 과정

- 전 코드에서 Main에서 작성한 코드들은 Kiosk 클래스에서 작성되며 Main 클래스에서는 Kiosk 클래스를 객체로 받아 Start() 메서드를 실행한다.

//Kiosk 객체를 생성하고 해당 객체에 있는 Start 메서드를 실행한다.
Kiosk kiosk = new Kiosk();
kiosk.Start();

- Kiosk 클래스에서 리스트에 햄버거 메뉴 정보를 저장하는 menuAdd 메서드를 생성했다.

//menuItemList 리스트에 메뉴를 저장하는 메서드
public void menuAdd(){
    menuItemList.add(new MenuItem("ShackBurger", 6.9, "토마토, 양상추, 쉑소스가 토핑된 치즈버거"));
    menuItemList.add(new MenuItem("SmokeShack", 8.9, "베이컨, 체리 페퍼에 쉑소스가 토핑된 치즈버거"));
    menuItemList.add(new MenuItem("Cheeseburger", 6.9, "포테이토 번과 비프패티, 치즈가 토핑된 치즈버거"));
    menuItemList.add(new MenuItem("Hamburger", 5.4, "비프패티를 기반으로 야채가 들어간 기본버거"));
}

- 입력 방식에는 메뉴에서 정의한 숫자 외의 숫자 입력, 문자 입력 총 두 가지의 오류가 존재하며, 각각 if문과 try_catch를 통해서 예외 처리를 했다.

try{
    System.out.println("원하는 메뉴 번호를 입력하시거나 종료 숫자를 입력하시면 됩니다.");
    checkNum=sc.nextInt();
    sc.nextLine();
    System.out.println();

    //0을 입력한 경우에 프로그램을 종료
    if(checkNum==0){
        System.out.println("프로그램을 종료합니다.");
        break;
    }
    //메뉴에 있는 숫자 외에 다른 숫자를 입력한 경우 오류 메세지 출력
    else if(checkNum>menuItemList.size()){
        System.out.println("메뉴에 있는 숫자만 입력해주세요!");
    }
    else{
        System.out.println("선택한 메뉴 : "+menuItemList.get(checkNum-1).foodName+", "+menuItemList.get(checkNum-1).foodPrice+", "+menuItemList.get(checkNum-1).foodInfo);
    }
}catch (Exception e){//숫자 외에 문자가 오는 경우 예외 처리
    sc.nextLine();
    System.out.println("숫자만 입력하실 수 있습니다!");
}

 

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

▷ 문제 풀이 시 요구사항

● Menu 클래스를 생성하여 MenuItem 클래스를 관리한다.

● 리스트는 Menu 클래스에서 관리한다.

● 카테고리 이름 필드를 갖는다.

● 메뉴 카테고리 이름을 반환하는 메서드가 구현되어야한다.

 

▷ 코드 제작 과정

- Kiosk 클래스는 오직 Start 메서드만 존재하도록 코드를 변경하였다.

- Menu 클래스에서는 카테고리, 버거, 음료, 디저트 리스트를 생성했다.

/*ArrayList 필드
각 음식 카테고리마다 리스트를 생성한다.*/
ArrayList<String> Category=new ArrayList<>();
ArrayList<MenuItem> burgerItemList =new ArrayList<>();
ArrayList<MenuItem> drinkItemList =new ArrayList<>();
ArrayList<MenuItem> dessertItemList =new ArrayList<>();

- 각각 리스트에 정보를 저장하고 열거하는 메서드를 생성했다.

- 숫자 입력에 따라 메뉴를 선택하고 출력하는 메서드를 생성했다.

 

▶ Lv 5. 캡슐화 적용하기

▷ 문제 풀이 시 요구사항

● 각 클래스의 필드에 직접 접근하지 못하도록 설정

● Getter와 Setter 메서드를 사용해 데이터를 관리한다.

 

▷ 코드 제작 과정

- 각 필드를 private로 직접 접근할 수 없도록 제작하고 각 필드의 값에 접근할 수 있는 Getter와 Setter 메서드를 생성했다.

ex) MenuItem 클래스

public class MenuItem {
    /*MeunItem 필드
    private를 통해 필드에 접근하지 못하게 제작
    */
    private String foodName;
    private double foodPrice;
    private String foodInfo;

    /*매개변수를 지닌 MenuItem 생성자
    생성자를 호출하여 각 MenuItem 필드에 값을 저장한다.*/
    public MenuItem(String foodName, double foodPrice, String foodInfo) {
        setFoodName(foodName);
        setFoodPrice(foodPrice);
        setFoodInfo(foodInfo);
    }

    //필드에 접근하는 get, set 메서드
    public String getFoodName() {
        return foodName;
    }

    public void setFoodName(String foodName) {
        this.foodName = foodName;
    }

    public double getFoodPrice() {
        return foodPrice;
    }

    public void setFoodPrice(double foodPrice) {
        this.foodPrice = foodPrice;
    }

    public String getFoodInfo() {
        return foodInfo;
    }

    public void setFoodInfo(String foodInfo) {
        this.foodInfo = foodInfo;
    }
}

 

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

▷ 문제 풀이 시 요구사항

● 주문한 상품을 담는 장바구니를 제작해야한다.

● 결제를 시도하기 전에 장바구니에 담긴 상품의 총 가격과 각 메뉴의 이름, 가격, 수량을 출력해야한다.

● 결제는 장바구니에 상품이 담겼을 경우 활성화되도록 제작해야한다.

● 주문하기를 누르면 장바구니에 담긴 상품들을 열거하고 총 가격을 출력해야한다.

● 취소를 누를 경우 장바구니를 초기화해야한다.

 

▷ 코드 제작 과정

- 상품들을 담는 장바구니 리스트를 제작

- 장바구니에 담긴 여부와 최종 확인 여부의 값을 저장하는 boolean 타입 필드 제작

private boolean orderBool=false;
private boolean finishOrder=false;

- 주문한 상품을 열거하고 최종 결제까지 진행하는 enumOrderList 메서드 제작

//주문한 제품들 열거하고 총 금액을 계산하는 메서드
public void enumOrderList(){
    double sum=0;
    System.out.println("아래와 같이 주문 하시겠습니까?");
    System.out.println();
    System.out.println("[ Orders ]");
    for(MenuItem menuItem : orderList){
        System.out.println(menuItem.getFoodName()+" | W "+menuItem.getFoodPrice()+" | "+menuItem.getFoodInfo());
        sum+=menuItem.getFoodPrice();
    }
    System.out.println();

    System.out.println("[ Total ]");
    System.out.println("W "+sum);
    System.out.println();
    while(true){
        try{
            System.out.println("1. 주문  2. 메뉴판");
            int orderNum=sc.nextInt();
            sc.nextLine();

            if(orderNum==1){
                System.out.println();
                System.out.println("주문이 완료되었습니다. 금액은 W "+sum+" 입니다.");
                setFinishOrder(true);
                break;
            }
            else if(orderNum==2){
                System.out.println();
                break;
            }
            else{
                System.out.println("메뉴에 있는 숫자만 입력해주세요!");
                System.out.println();
            }
        } catch (Exception e) {
            sc.nextLine();
            System.out.println("숫자만 입력하실 수 있습니다!");
            System.out.println();
        }
    }
}

 

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

▷ 문제 풀이 시 요구사항

● Enum을 활용하여 사용자 유형별 할인율을 관리해야한다.

● 람다 & 스트림을 활용하여 장바구니 조회 기능을 구현해야한다.(미구현)

 

▷ 코드 제작 과정

- 각 유형마다 적용되는 할인율이 있는 Discount Enum 클래스를 제작했다.

public enum Discount {
    PNM("국가유공자",0.1),
    SOLDIER("군인",0.05),
    STUDENT("학생",0.03),
    PEOPLE("일반",0);

    private String dType;
    private double discount;

    Discount(String dType, double discount) {
        this.dType = dType;
        this.discount = discount;
    }

    public String getDType() {
        return dType;
    }

    public double getDiscount() {
        return discount;
    }
}

- 기존 코드에서 장바구니 내의 상품의 총 금액을 계산한 후 결제 진행 시 할인 유형을 고를 수 있는 메뉴가 나올 수 있도록 코드를 수정했다.

public void enumOrderList(){
    double sum=0;
    System.out.println("아래와 같이 주문 하시겠습니까?");
    System.out.println();
    System.out.println("[ Orders ]");
    for(MenuItem menuItem : orderList){
        System.out.println(menuItem.getFoodName()+" | W "+menuItem.getFoodPrice()+" | "+menuItem.getFoodInfo());
        sum+=menuItem.getFoodPrice();
    }
    System.out.println();

    System.out.println("[ Total ]");
    System.out.println("W "+sum);
    System.out.println();
    while(true){
        try{
            System.out.println("1. 주문  2. 메뉴판");
            int orderNum=sc.nextInt();
            sc.nextLine();

            if(orderNum==1){
                int index=1;

                System.out.println();
                System.out.println("할인 정보를 입력해주세요.");
                for(Discount d : Discount.values()){
                    System.out.println(index+". "+d.getDType()+" : "+d.getDiscount()*100+"%");
                    index++;
                }

                while(true){
                    try{
                        int discountNum=sc.nextInt();
                        sc.nextLine();

                        //입력한 번호마다 할인률 적용
                        if(discountNum==1){
                            sum=sum-(sum*Discount.PNM.getDiscount());
                            break;
                        }
                        else if(discountNum==2){
                            sum=sum-(sum*Discount.SOLDIER.getDiscount());
                            break;
                        }
                        else if(discountNum==3){
                            sum=sum-(sum*Discount.STUDENT.getDiscount());
                            break;
                        }
                        else if(discountNum==4){
                            sum=sum-(sum*Discount.PEOPLE.getDiscount());
                            break;
                        }
                        else{
                            System.out.println("메뉴에 있는 숫자만 입력해주세요!");
                        }
                    } catch (Exception e) {
                        sc.nextLine();
                        System.out.println("숫자를 입력해주세요!");
                    }
                }

                System.out.println("주문이 완료되었습니다. 금액은 W "+sum+" 입니다.");
                setFinishOrder(true);
                break;
            }
            else if(orderNum==2){
                System.out.println();
                break;
            }
            else{
                System.out.println("메뉴에 있는 숫자만 입력해주세요!");
                System.out.println();
            }
        } catch (Exception e) {
            sc.nextLine();
            System.out.println("숫자만 입력하실 수 있습니다!");
            System.out.println();
        }
    }
}

'TIL' 카테고리의 다른 글

내일배움캠프 TIL 19.  (0) 2025.01.21
내일배움캠프 TIL 18.  (0) 2025.01.20
내일배움캠프 TIL 17.  (0) 2025.01.17
내일배움캠프 TIL 16.  (0) 2025.01.16
내일배움캠프 TIL 15.  (1) 2025.01.15