사이먼's 코딩노트

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

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

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

simonpark817 2024. 4. 16. 23:02

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

 

GitHub - psm817/hotel_booking_proj

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

github.com

 

[간단한 아스키아트 추가]

  • 이번에는 크게 비중을 차지하지는 않지만, 개성을 보이기 위해 간단한 아스키아트를 추가해보려한다.
  • 아스키아트란 오로지 텍스트와 특수문자만을 조합하여 사진이나 그림을 흉내내는 것을 의미한다.
  • 필자는 아스키아트로 객실의 위치를 표현하고 싶어, 간단하게 코드를 추가하였고 해당 코드는 호텔의 기본 정보이기 때문에 HotelController.java 클래스에 추가하였다.
package org.example.controller;

import java.util.Scanner;

public class HotelController extends Controller {
    private Scanner sc;
    private String cmd;

    public HotelController() {
        sc = new Scanner(System.in);
    }

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

        switch(actionMethodName) {
            case "introduce" :
                doIntroduce();
                break;
            default :
                System.out.println("존재하지 않는 서비스입니다.");
        }
    }

    private void doIntroduce() {
        System.out.printf("\n");
        System.out.println("======== 호텔 소개 ========");
        System.out.println("호텔명 : 대전 그랜드 호텔");
        System.out.println("호텔 위치 : 대전광역시 서구 청사로 111 (3 ~ 5층)");
        System.out.println("호텔 전화번호 : 042-123-1234");
        System.out.println("카운터 영업시간 : 오전 8시 ~ 오후 12시");
        System.out.println("객실 구성 : 각 층별로 10개");
        System.out.println("객실 종류 : 싱글(홀수) / 더블(짝수)");
        System.out.println("객실 최대 수용 인원 : 싱글(2인) / 더블(4인)");
        System.out.println("객실 요금 : 싱글(150,000원) / 더블(250,000원) ");
        System.out.println("** 객실 예약은 일주일 단위로 가능 **");
        System.out.println("** 인원 추가 시 20,000원 추가 **");
        System.out.println("===========================");
        System.out.printf("\n");

        System.out.println("======== 객실 위치 ========");
        System.out.println("*** 층별로 위치는 동일 ***");
        System.out.println("━━━━━┓\n" +
                "┓┓┓┓┓┃         ┎━━━━━━┒      ┎━━━━━━┒      ┎━━━━━━┒\n" +
                "┓┓┓┓┓┃         ┃┏┓┏┓┏┓┃      ┃┏┓┏┓┏┓┃      ┃┏┓┏┓┏┓┃\n" +
                "┓┓┓┓┓┃         ┃┏┓┏┓┏┓┃      ┃┗┛┗┛┗┛┃      ┃┗┛┗┛┗┛┃\n" +
                "┓┓┓┓┓┃         ┃┏┓┏┓┏┓┃      ┃┏┓┏┓┏┓┃      ┃┏┓┏┓┏┓┃\n" +
                "┓┓┓┓┓┃ 엘         1호           3호           5호\n" +
                "┓┓┓┓┓┃ 리\n" +
                "┓┓┓┓┓┃ 베\n" +
                "┓┓┓┓┓┃ 이\n" +
                "┓┓┓┓┓┃ 터          ┎━━━━━━━━━━┒    ┎━━━━━━━━━━┒\n" +
                "┓┓┓┓┓┃            ┃┏┓┏┓┏┓┏┓┏┓┃    ┃┏┓┏┓┏┓┏┓┏┓┃\n" +
                "┓┓┓┓┓┃            ┃┗┛┗┛┗┛┗┛┗┛┃    ┃┗┛┗┛┗┛┗┛┗┛┃\n" +
                "┓┓┓┓┓┃            ┃┏┓┏┓┏┓┏┓┏┓┃    ┃┏┓┏┓┏┓┏┓┏┓┃\n" +
                "┓┓┓┓┓┃                 2호              4호");
        System.out.println("===========================");

    }

}
  • 안내하고자 하는 것은 모든 층별로 객실의 위치는 호수마다 일치하다는 것이다.
  • 객실은 좌측의 엘리베이터를 기준으로 좌측에 싱글룸인 1, 3, 5호가 배치되어 있고 우측에는 더블룸인 2, 4호가 배치되어 있다.

 

[객실 예약 구현]

  • 다음은 프로그램의 핵심 기능인 객실 예약 'booking room'을 구현해보고자 한다.
  • 예약과 관련된 기능들은 모두 BookingController.java 클래스에 코드를 추가하였다.
  • 먼저 예약과 연관된 모든 정보들은 Booking.java 클래스에서 관리하고 아래는 booking에 필요한 변수들이다.
package org.example.dto;

public class Booking extends Dto {
    public String regDate;
    public String guestName;
    public String guestPhone;
    public int roomType;

    public Booking(int id, String regDate, String guestName, String guestPhone, int roomType) {
        this.id = id;
        this.regDate = regDate;
        this.guestName = guestName;
        this.guestPhone = guestPhone;
        this.roomType = roomType;
    }
}
  • 예약번호를 뜻하는 고유번호 id는 Dto에서 공통으로 관리중이기 때문에 마찬가지로 Dto을 상속받도록 하였다.
  • 예약에 필요한 데이터들은 예약등록날짜, 예약자이름, 예약자 전화번호, 객실타입이고 생성자를 통해 각 정보를 저장한다.

 

package org.example.controller;

import org.example.Util;
import org.example.dto.Booking;
import org.example.dto.Guest;
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;
    private 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;
            default :
                System.out.println("존재하지 않는 서비스입니다.");
                break;
        }
    }

    public void doBooking() {
        String[] cmdBits = cmd.split(" ");
        if(cmdBits.length > 2) {
            System.out.println("존재하지 않는 서비스입니다.");
            return;
        }

        System.out.print("예약할 객실 호수 입력) ");
        int roomNum = sc.nextInt();
        sc.nextLine();

        // 날짜 입력 및 7일간 날짜 판단
        System.out.print("예약 날짜 입력) ");
        String bookingDate = sc.nextLine();
        bookingDate = bookingDate.trim();

        if(Util.checkWeekDate(bookingDate) == false) {
            System.out.println("오늘 날짜부터 7일간 조회 가능합니다.");
            return;
        }

        // 예약가능한 객실 가져오기
        bookingAbleRoom = getRoomsByNum(roomNum);

        // 객실이 없거나, 예약불가 처리
        if(bookingAbleRoom == null || bookingAbleRoom.booked.equals("예약불가")) {
            System.out.println("예약이 불가능한 객실입니다.");
            return;
        }

        // 객실 타입 안내
        if(roomNum % 2 == 1) {
            System.out.printf("*** %d호 객실의 타입은 [%d] ***\n", roomNum, bookingAbleRoom.type);
        }
        else if(roomNum % 2 == 0) {
            System.out.printf("*** %s호 객실의 타입은 [%s] ***\n", roomNum, bookingAbleRoom.type);
        }

        Booking booking = null;

        while(true) {
            int id = bookings.size() + 1;
            System.out.print("예약이 가능합니다. 예약을 진행할까요?) ");
            String answer = sc.nextLine();
            answer = answer.trim();

            if(answer.equals("yes")) {
                // booking 배열 추가
                booking = new Booking(id, bookingDate, loginedGuest.name, loginedGuest.phoneNum, bookingAbleRoom.type);
                bookings.add(booking);

                // 로그인된 회원의 이름으로 예약 성공
                System.out.printf("%s님 예약 성공하셨습니다!!\n", booking.guestName);
                System.out.println("결제는 당일 카운터에서 진행 부탁드립니다!");

                break;
            }

            else if(answer.equals("no")) {
                System.out.println("예약을 중단합니다.");
                break;
            }

            else {
                System.out.println("\'yes\' 또는 \'no\'를 입력해주세요");
                continue;
            }
        }

        // room 상태를 예약불가로 변경
        bookingAbleRoom.booked = "예약불가";
        bookingAbleRoom.bookingDate = bookingDate;
    }
    
    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;
    }
}
  • 객실 예약의 서비스 명령어는 'booking room' 이고 서비스가 실행됨과 동시에 예약할 객실 호수를 입력받는다.
  • 그 다음 예약하고 싶은 날짜를 입력받고, 만약 현재 날짜를 기준으로 일주일 안에 속하지 않는다면 예약이 불가능하다.
  • 일주일 안에 속하는 날짜를 선택했다면 사용자가 선택한 객실 번호가 예약이 가능한지 예약여부를 확인하고 만약 Room 타입인 bookingAbleRoom의 booked가 '예약불가' 라면 에약이 불가능하다.
  • booked가 '예약가능' 이라면 그 다음 단계로, 객실 번호의 홀/짝을 확인하여 객실 타입을 구분한다.
  • 마지막으로 예약을 진행하겠냐는 질문을 통해 yes 또는 no로 대답을 받고, 만약 yes라면 bookings 리스트에 로그인된 회원의 이름, 전화번호, 예약날짜, 객실타입을 add() 통해 저장한다.
  • 예약에 성공했다면 가장 아래에서 예약이 완료된 날짜의 객실번호의 예약여부를 반드시 '예약불가' 로 변경하여 다른 사용자와의 예약이 중복되지 않도록 해준다.

 

[객실 예약 시 인원 체크]

  • 위에서 1차 구현된 객실 예약 기능에서 이제 세부적으로 인원 체크를 하는 로직을 추가하려한다.
  • 아래 코드는 BookingController.java 클래스에서 doBooking() 메서드만 보여드린 점 참고 부탁드립니다. 
public void doBooking() {
    String[] cmdBits = cmd.split(" ");
    if(cmdBits.length > 2) {
        System.out.println("존재하지 않는 서비스입니다.");
        return;
    }

    System.out.print("예약할 객실 호수 입력(숫자만) : ");
    int roomNum = sc.nextInt();
    sc.nextLine();


    // 날짜 입력 및 7일간 날짜 판단
    System.out.print("예약 날짜 입력) ");
    String bookingDate = sc.nextLine();
    bookingDate = bookingDate.trim();

    if(Util.checkWeekDate(bookingDate) == false) {
        System.out.println("오늘 날짜부터 7일간 조회 가능합니다.");
        return;
    }

    // 예약가능한 객실 가져오기
    bookingAbleRoom = getRoomsByNum(roomNum);

    // 객실이 없거나, 예약불가 처리
    if(bookingAbleRoom == null || bookingAbleRoom.booked.equals("예약불가")) {
        System.out.println("예약이 불가능한 객실입니다.");
        return;
    }

    // 요금 안내
    int payment = 150000;
    int count = 0;
    int plusPay = 20000;

    // 객실 타입 안내
    if(roomNum % 2 == 1) {
//            System.out.printf("*** %d호 객실의 타입은 [%d] ***\n", roomNum, bookingAbleRoom.type);
        System.out.print("인원은 몇 명 이신가요?) ");
        int peopleNum = sc.nextInt();
        sc.nextLine();

        if(peopleNum > 2) {
            count = peopleNum - 2;
            System.out.println("[싱글] 정원 2명을 초과하셨습니다!!");
            System.out.println("추가 인원 당 20,000원의 추가 요금이 발생합니다!!");
        }
    }
    else if(roomNum % 2 == 0) {
        payment += 100000;
        System.out.print("인원은 몇 명 이신가요?) ");
        int peopleNum = sc.nextInt();
        sc.nextLine();

        if(peopleNum > 4) {
            count = peopleNum - 4;
            System.out.println("[더블] 정원 4명을 초과하셨습니다!!");
            System.out.println("추가 인원 당 20,000원의 추가 요금이 발생합니다!!");
        }
    }

    Booking booking = null;

    while(true) {
        int id = bookings.size() + 1;
        System.out.print("예약을 진행할까요?) ");
        String answer = sc.nextLine();
        answer = answer.trim();

        if(answer.equals("yes")) {
            // booking 배열 추가
            booking = new Booking(id, bookingDate, loginedGuest.name, loginedGuest.phoneNum, bookingAbleRoom.type);
            bookings.add(booking);

            // 로그인된 회원의 이름으로 예약 성공
            System.out.printf("%s님 예약 성공하셨습니다!!\n", booking.guestName);
            System.out.printf("총 금액은 %d입니다. 결제는 당일 카운터에서 진행 부탁드립니다!\n", (payment+(count*plusPay)));

            break;
        }

        else if(answer.equals("no")) {
            System.out.println("예약을 중단합니다.");
            break;
        }

        else {
            System.out.println("\'yes\' 또는 \'no\'를 입력해주세요");
            continue;
        }
    }

    // room 상태를 예약불가로 변경
    bookingAbleRoom.booked = "예약불가";
    bookingAbleRoom.bookingDate = bookingDate;
}
  • 일단 현재 프로그램의 호텔 컨셉 상 싱글룸은 최대 2인이 숙박이 가능하고, 더블룸은 최대 4인이 숙박이 가능하다.
  • 인원에 관계없이 싱글룸의 요금(payment)은 150,000원이고, 더블룸은 250,000원이다.  
  • 만약 각 객실 타입 기준으로 인원을 초과했을 경우에는 20,000원의 추가 요금(plusPay)이 발생한다.
  • 위 시나리오를 바탕으로 객실 예약 기능을 수정했고, 객실 타입을 구분하는 조건문 안에 인원이 몇 명인지 체크하고 만약 2인 또는 4인을 넘어서게 되면 초과된 인원을 count라는 변수에 저장하고, 예약이 완료되었을 때 각 객실 타입에 맞게 payment, count, plusPay를 계산하여 사용자에게 총 요금을 안내한다.
반응형