사이먼's 코딩노트

[Java] 호텔 예약 관리 프로그램 제작(7) 본문

프로젝트/[Java] 호텔 예약 관리 프로그램 제작

[Java] 호텔 예약 관리 프로그램 제작(7)

simonpark817 2024. 4. 17. 14:31

[호텔 예약 관리 프로그램 제작]

 

GitHub - psm817/hotel_booking_proj

Contribute to psm817/hotel_booking_proj development by creating an account on GitHub.

github.com

 

[예약 취소 구현]

  • 이번에는 객실 예약을 한 사용자가 본인의 예약 건을 취소하기 위한 'booking delete' 를 구현해보고자 한다.
  • 예약과 관련된 기능들은 모두 BookingController.java 클래스에 코드를 추가하였다.
package org.example.controller;

import org.example.Util;
import org.example.dto.Booking;
import org.example.dto.Room;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class BookingController extends Controller {
    private Scanner sc;
    private String cmd;
    public static List<Booking> bookings;
    public Room bookingAbleRoom;

    public BookingController() {
        sc = new Scanner(System.in);
        bookings = new ArrayList<>();
    }

    public void doAction(String cmd, String actionMethodName) {
        this.cmd = cmd;

        switch(actionMethodName) {
            case "room" :
                doBooking();
                break;
            case "check" :
                doCheckBooking();
                break;
            case "delete" :
                doDeleteBooking();
                break;
            default :
                System.out.println("존재하지 않는 서비스입니다.");
                break;
        }
    }

    public void doDeleteBooking() {
        int foundBookingCount = getBookingsByName(loginedGuest.name);
        System.out.printf("%s 님, 총 [%d]건의 예약이 있습니다.\n", loginedGuest.name, foundBookingCount);

        if(foundBookingCount == 0) {
            System.out.println("취소하실 예약 건이 없습니다.");
        }
        else {
            System.out.printf("==== [%s 님] 예약 현황 =======\n", loginedGuest.name);
            System.out.println("예약번호 | 호수 | 예약날짜");

            for (int i = 0; i < bookings.size(); i++) {
                Booking bookedAllRoom = bookings.get(i);

                for(int j = 0; j < rooms.size(); j++) {
                    Room foundAllRoom = rooms.get(j);
                    int roomId = foundAllRoom.floor * 100 + foundAllRoom.id;

                    if(bookedAllRoom.regDate.equals(foundAllRoom.bookingDate) && bookedAllRoom.roomId == roomId && loginedGuest.name.equals(bookedAllRoom.guestName)) {
                        System.out.printf("    %4d |  %d | %s\n", bookedAllRoom.id, bookedAllRoom.roomId, bookedAllRoom.regDate);
                    }
                }
            }
            System.out.println("====================================");
            System.out.print("예약을 취소하시겠습니까?) ");
            String answer = sc.nextLine();

            Booking foundBooking = foundBookedRoomByName(loginedGuest.name);
            Room foundRoom = getRoomsByNum(foundBooking.roomId);

            if(answer.equals("yes")) {
                System.out.print("취소하시고 싶은 예약번호를 입력(숫자만) : ");
                int answerId = sc.nextInt();
                sc.nextLine();

                if(answerId == foundBooking.id) {
                    bookings.remove(foundBooking);
                    foundRoom.bookingDate = null;
                    foundRoom.booked = "예약가능";

                    System.out.println("예약이 취소되었습니다!!");
                }
            }
            else if(answer.equals("no")) {
                System.out.println("예약취소를 중단합니다.");
            }
            else {
                System.out.println("\'yes\' 또는 \'no\'를 입력해주세요");
            }
        }
    }

    public Room getRoomsByNum(int roomNum) {
        int index = getRoomsIndexByNum(roomNum);

        if(index != -1) {
            return rooms.get(index);
        }

        return null;
    }

    public int getRoomsIndexByNum(int roomNum) {
        int i = 0;

        for(Room room : rooms) {
            if((room.floor * 100 + room.id) == roomNum) {
                return i;
            }
            i++;
        }

        return -1;
    }

    private int getBookingsByName(String name) {
        int sum = 0;

        for(Booking booking : bookings) {
            if(booking.guestName.equals(name)) {
                sum++;
            }
        }

        return sum;
    }

    private Booking foundBookedRoomByName(String name) {
        int i = 0;

        for(Booking booking : bookings) {
            if(booking.guestName.equals(name)) {
                return bookings.get(i);
            }
            i++;
        }

        return null;
    }
}
  • 먼저 서비스 명령어를 구분하기 위해 doAction() 메서드에서 'delete' 라는 문자열을 통해 doDeleteBooking() 메서드를 호출하도록 한다.
  • 예약 취소는 로그인이 된 회원에 한해서만 취소가 가능하고, 회원은 본인이 예약한 내역을 먼저 볼 수 있다.
  • doDeleteBooking() 메서드가 호출됨과 동시에 총 몇 건의 예약이 있는지 확인이 가능하다.
  • 만약 예약한 이력이 없다면 취소할 예약 건이 없다는 안내와 함께 해당 서비스가 종료된다.
  • 그렇지 않다면 booking check와 마찬가지로 조건문을 통해 예약한 날짜와 객실번호가 모두 일치하면  자동으로 로그인 된 회원의 모든 예약 현황을 보여준다.
  • 그 다음, 예약을 취소하겠냐는 질문이 나오게 되고 만약 취소를 원한다면 해당 예약 건의 예약번호를 입력한다.
  • 여기서 말하는 예약번호는 bookings에 하나씩 쌓이는 고유 id를 뜻한다.
  • 만약 사용자가 입력한 예약번호와 foundBookedRoomByName() 메서드를 통해 가져온 예약의 정보의 id와 일치한다면 예약이 취소되었다는 안내와 함께 기존에 예약했던 날짜에 해당하는 객실의 예약여부를 '예약가능' 으로 변경하고 예약된 날짜인 bookingDate를 null 값으로 채워준다.
  • 추가로 bookings 리스트에 저장된 해당 예약 건을 remove() 를 이용하여 삭제한다.
  • 해당 작업을 하는 이유는 해당 회원이 예약을 취소하게 되면 다른 회원들이 객실 예약을 할 수 있게끔 하기 위해서다.
  • 무한루프를 사용하여 만약 사용자가 예약 취소를 원하지 않는다면 해당 메서드를 종료하고, yes나 no가 아닌 다른 대답을 했다면 대답이 잘못되었다는 안내와 함께 다시 예약 취소를 원하는 지 질문한다.

 

[문제점 개선]

  • 현재 상태에서 프로그램을 실행했을 때, 각 회원이 오직 하나의 예약을 했다고 가정한다면 각 회원의 예약 취소 기능은 문제없이 동작한다.
  • 하지만 2개 이상의 예약을 했다면 예약 취소 시 원하는 예약번호에 맞춰 예약 건이 취소되지 않고 무조건 첫번째 예약 건이 삭제된다.
  • 위 문제는 예약을 취소하고자 하는 객실을 반복문을 통해 가져오는 과정에서 조건문을 통해 무조건 예약 번호만 같다면 삭제가 되도록 구현했기 때문이다.
  • 해당 문제를 개선하기 위해 약간의 코드를 수정하였다.
public void doDeleteBooking() {
    int foundBookingCount = getBookingsByName(loginedGuest.name);
    System.out.printf("%s 님, 총 [%d]건의 예약이 있습니다.\n", loginedGuest.name, foundBookingCount);

    if(foundBookingCount == 0) {
        System.out.println("취소하실 예약 건이 없습니다.");
    }
    else {
        System.out.printf("==== [%s 님] 예약 현황 =======\n", loginedGuest.name);
        System.out.println("예약번호 | 호수 | 예약날짜");

        for (int i = 0; i < bookings.size(); i++) {
            Booking bookedAllRoom = bookings.get(i);

            for(int j = 0; j < rooms.size(); j++) {
                Room foundAllRoom = rooms.get(j);
                int roomId = foundAllRoom.floor * 100 + foundAllRoom.id;

                if(bookedAllRoom.regDate.equals(foundAllRoom.bookingDate) && bookedAllRoom.roomId == roomId && loginedGuest.name.equals(bookedAllRoom.guestName)) {
                    System.out.printf("    %4d |  %d | %s\n", bookedAllRoom.id, bookedAllRoom.roomId, bookedAllRoom.regDate);
                }
            }
        }

        System.out.println("====================================");
        System.out.print("예약을 취소하시겠습니까?) ");
        String answer = sc.nextLine();

        if(answer.equals("yes")) {
            System.out.print("취소하시고 싶은 예약번호를 입력(숫자만) : ");
            int answerId = sc.nextInt();
            sc.nextLine();

            for(int i = 0; i < bookings.size(); i++) {
                Booking bookedAllRoom = bookings.get(i);

                for(int j = 0; j < rooms.size(); j++) {
                    Room foundAllRoom = rooms.get(j);
                    int roomId = foundAllRoom.floor * 100 + foundAllRoom.id;

                    if(bookedAllRoom.regDate.equals(foundAllRoom.bookingDate) && bookedAllRoom.roomId == roomId && loginedGuest.name.equals(bookedAllRoom.guestName)) {
                        if(bookedAllRoom.id == answerId) {
                            bookings.remove(bookedAllRoom);
                            foundAllRoom.bookingDate = null;
                            foundAllRoom.booked = "예약가능";

                            System.out.println("예약이 취소되었습니다!!");
                        }
                    }
                }
            }
        }
        else if(answer.equals("no")) {
            System.out.println("예약취소를 중단합니다.");
        }
        else {
            System.out.println("\'yes\' 또는 \'no\'를 입력해주세요");
        }
    }
}
  • 2개 이상의 예약 건이 있을 경우를 생각하여 취소하고 싶은 예약번호를 회원이 입력한 후에 이중 반복문을 사용하여 bookedAllRoom과 foundAllRoom 변수를 통해 전체 예약 건과 객실을 하나씩 살핀다.
  • 이 때 객실번호를 추출하기 위해서 foundAllRoom의 층을 나타내는 floor에 100을 곱한 후, 호수인 id를 더하여 roomId 변수를 하나 선언한다.
  • 그리고 조건문을 통해 예약날짜와 객실 번호, 예약자 이름이 모두 같다는 조건을 두어 원하는 예약번호를 입력했을 때 삭제 가능하도록 한다.

 

 

반응형