프로젝트 진행 계기
학원에서 수업 중 자바를 거의 다 배우고 객실 예약 프로그램이라는 마지막 과제를 끝냈다.
해당 프로그램은 단순히 101호에서 303호까지의 방을 예약하고 취소하고
현재 예약 현황을 조회하는 정도의 간단한 프로그램이었다.
하지만 해당 과제를 진행하고 나서 나는 좀 더 욕심이 생겼다.
객실 예약이라는건 고객의 정보를 바탕으로 예약이 되어야하지 않을까?
연장이나 취소등을 자유롭게 해야할 수 있지 않을까? 등등.. 많은 기능을 담고 싶어졌다.
어쩌면 정말 사용할만한 제대로된 프로그램이란걸 만들어보고 싶단 욕심이 생겼던 것 같다.
그래서 개인적으로 과제로 진행했던 객실 예약프로그램을 더욱 업그레이드 하여
호텔 예약 프로그램이라는 나름 거창한 이름으로 해당 미니 프로젝트를 진행하였다.
아직 데이터베이스를 배우기 전에 진행했던 프로젝트로 고객정보를 실제로 저장하고 유지할 수는 없었지만
최대한 프로그램이 실행되는 중에는 입력하고 진행했던 모든 정보를 유지할 수 있도록 만들었다.
프로젝트 소개
호텔 예약 시스템은 호텔 프론트에서 각종 예약 업무를 진행할 수 있도록 설계하였다.
기능
- 고객 정보 입력을 통한 호텔 예약 시스템
- 오늘 예약과 예약일 지정 가능
- 원하는 호실 지정과 랜덤 배정 가능
- 연박 가능
- 고객 검색 기능(동명이인 검색 시 정보를 통한 선택 가능)
- 예약 취소 가능
- 예약 연장 가능
- 현재 예약 현황 조회 가능
- 예약 시 매출 연동
- 현재 영업 현황 조회 가능
주요 클래스
- Guest 클래스
- ReservationDay 클래스
- Main 클래스
Guest 클래스
- 예약자의 정보와 각종 예약 처리 기능을 가지고 있는 클래스이다.
주요 메서드
- guestSet() - 고객 정보 입력 메서드
- datecheck() - 예약일 확인 메서드
- roomcheck() - 예약일 연박 생성 메서드
- roomSet() - 룸 예약 메서드
- roomReservation_now() - 오늘 예약 메서드
- roomReservation_later() - 예약일 지정 메서드
- getInfo() - 정보 출력 메서드
- roomCancle() - 예약 취소 메서드
- roomReservationChange() - 예약 연장 메서드
코드
package ReservationSystem;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
public class Guest {
int room;
String name;
int gender;
int age;
int people;
int day;
int money;
int year;
int month;
int date;
int search;
String money_s;
String reser;
String reser_e;
String format_s;
String format_e;
Calendar now;
Calendar in;
Calendar out;
Calendar ing;
SimpleDateFormat sdf1;
SimpleDateFormat sdf2;
public Guest() {
room = 0;
name = "무명";
gender = 0;
age = 0;
people = 0;
day = 0;
money = 0;
year = 0;
month = 0;
date = 0;
search = 0;
money_s = "";
sdf1 = new SimpleDateFormat("yyyyMMdd");
sdf2 = new SimpleDateFormat("yyyy년 MM월 dd일");
}
/*
* 고객정보 입력 메서드
*
* 고객 정보를 차례로 입력받되 성별 입력에서 1(남), 2(여)가 아닌
* 다른 숫자가 입력되면 잘못 입력 문자 표시 후
* 본인 메서드를 다시 실행하여 재입력
* 이때 다시 나머지 입력을 반복하지 않기 위해 return
*/
public void guestSet(Scanner sc) {
System.out.println();
System.out.print(" * 고객 성함 : ");
name = sc.nextLine();
System.out.print(" * 고객 성별 (남 1 / 여 2) : ");
gender = sc.nextInt();
sc.nextLine();
if (gender < 0 || gender > 2) {
System.out.println(" -- 잘못 입력하였습니다. -- ");
guestSet(sc);
return;
}
System.out.print(" * 고객 나이 : ");
age = sc.nextInt();
sc.nextLine();
System.out.print(" * 숙박 인원 : ");
people = sc.nextInt();
sc.nextLine();
System.out.print(" * 숙박 일수 : ");
day = sc.nextInt();
sc.nextLine();
}
/*
* 예약일 객체 확인 메서드
*
* 예약일 객체 모음인 arr2를 체크 arr2의 사이즈만큼 반복하여 확인했을 때
* 예약 시 지정된 날짜(reser)가 확인 중인 객체의 예약일 변수(date)에 이미 있다면
* 카운트(cnt)를 하여 넘어감
*
* 그 카운트가 한번도 늘어나지 않고 0이라면 새로운 예약일 객체를 생성 후
* 방금 만든 객체(arr2.size() - 1)의 date에
* reser 값 입력
*/
public void datecheck(ArrayList<ReservationDay> arr2) {
int cnt = 0;
for (int i = 0; i < arr2.size(); i++) {
if (arr2.get(i).date.equals(reser)) {
cnt++;
}
}
if (cnt == 0) {
arr2.add(new ReservationDay());
arr2.get(arr2.size() - 1).date = reser;
}
}
/*
* 예약일 연박 생성 메서드
*
* 입력된 숙박일수(day)만큼 반복하여 연박 시 체크인과 체크아웃 사이의 날짜도 예약으로 처리
*
* Calendar 클래스를 사용하여 체크인 날짜를 멤버변수 ing에 입력
* 이때 반복을 위한 변수인 z(0 ~ (day-1))를 일 수에 더해서 입력
* 당일, 당일 + 1, 당일 + 2....로 비교하며 진행
*
* 날짜를 비교하기 위한 문자열 포맷(ex.20250101)으로 변환 후 reser_i에 저장
* 예약일 날짜 객체 모음(arr2)에 해당 날짜(reser_i)가 있다면
* 카운트 후 해당 인덱스를 a에 저장
*
* 카운트가 한번도 안되어 0이라면
* 예약일 객체를 하나 생성하고 해당 객체에 날짜와 방 예약 정보를 입력
*
* 카운트가 되어 이미 해당 날짜 객체가 있다면
* 아까 저장한 a를 인덱스로 사용하여 해당 날짜에 방 예약 정보를 입력
*/
public void roomcheck(ArrayList<ReservationDay> arr2) {
for (int z = 0; z < day; z++) {
int cnt = 0;
int a = 0;
ing = Calendar.getInstance();
ing.set(Calendar.YEAR, year);
ing.set(Calendar.MONTH, month - 1);
ing.set(Calendar.DAY_OF_MONTH, date + z);
String reser_i = sdf1.format(ing.getTime());
for (int k = 0; k < arr2.size(); k++) {
if (arr2.get(k).date.equals(reser_i)) {
cnt++;
a = k;
}
}
if (cnt == 0) {
arr2.add(new ReservationDay());
arr2.get(arr2.size() - 1).date = reser_i;
arr2.get(arr2.size() - 1).map.put(room, true);
} else {
arr2.get(a).map.put(room, true);
}
}
}
/* 룸 예약 메서드
*
* 원하는 호실이 있는지 물어보는 프롬프트 출력
*
* 있을 시(Y)
*
* 호실 입력(room) 후 해당 호실과 이전에 받은 예약일을 예약일 객체모음(arr2)에 비교하여
* 날짜도 같고 호실도 예약중일 때(true)
* 예약이 이미 있다는 메세지 출력 후 room을 다시 0으로 초기화
* 그리고 룸 예약 메서드를 다시 실행 - 반복되지 않게 return
*
* 만약 날짜는 같으나 해당 호실이 예약중이 아닐때(false)
* 예약 연박 생성 메서드(roomcheck)를 실행 후 break
*
* 없을 시(N)
*
* 방을 랜덤 배정하기 위해 101~303호까지 반복
* 여기서 반복을 할 땐 i가 100으로 나눴을 때 나머지가 3이 되는 수라면
* i를 97을 더해서 103->201 로 시작하여 확인할 수 있도록 조건문 처리
*
* 호실을 i로 두고 arr2가 예약일도 같고 방이 예약중이 아닐 때(false)
* 호실 변수(room)에 i를 저장하고
* 예약 연박 생성 메서드(roomcheck)를 실행 후 break
*
* 메서드를 실행 후 i가 호실 번호와 일치한다면 break
* 하지만 호실 번호가 바뀌지 않고(0) i가 303인 상태라면
* 모든 방이 예약중이므로 해당 메세지 출력 후
* 날짜 지정 예약 메서드 실행 후 return
* */
public void roomSet(Scanner sc, int hotelmoney, DecimalFormat format, ArrayList<ReservationDay> arr2) {
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 원하시는 호실이 있나요? * ");
System.out.println();
System.out.print(" * Y / N : ");
String ny = sc.nextLine();
if (ny.charAt(0) == 'Y' || ny.charAt(0) == 'y') {
System.out.println();
System.out.print(" * 원하시는 호실을 입력해 주세요 : ");
room = sc.nextInt();
sc.nextLine();
for (int i = 0; i < arr2.size(); i++) {
if (arr2.get(i).date.equals(reser)) {
if (arr2.get(i).map.get(room)) {
System.out.println();
System.out.println(" -- " + room + "호는 예약이 있습니다. -- ");
room = 0;
roomSet(sc, hotelmoney, format, arr2);
return;
}else {
roomcheck(arr2);
break;
}
}
}
} else if (ny.charAt(0) == 'N' || ny.charAt(0) == 'n') {
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 룸을 랜덤 배정합니다. * ");
for (int i = 101; i <= 303; i++) {
for (int j = 0; j < arr2.size(); j++) {
if (arr2.get(j).date.equals(reser)) {
if (!(arr2.get(j).map.get(i))) {
room = i;
roomcheck(arr2);
break;
}
}
}
if (room == i) {
break;
} else if (i == 303 && room == 0) {
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" -- 해당 날짜의 모든 방이 예약되었습니다. -- ");
System.out.println(" -- 다른 날짜로 예약해주세요. -- ");
roomReservation_later(sc, hotelmoney, format, arr2);
return;
}
if (i % 100 == 3) {
i += 97;
}
}
} else {
System.out.println();
System.out.println(" -- 잘못 입력하였습니다. -- ");
roomSet(sc, hotelmoney, format, arr2);
return;
}
}
/* 오늘 예약 메서드
*
* 체크인 변수(in)에 오늘 날짜를 세팅
* 문자열 비교를 위한 포맷 sdf1과 출력을 위한 포맷인 sdf2를 각각
* 멤버변수 reser와 format_s에 저장
*
* 해당 날짜로 예약일 객체 확인 메서드 실행
* 고객정보 입력 메서드 실행
* 룸 예약 메서드 실행
* 각 메서드를 실행하여 나온 결과를 출력할 수 있도록 getInfo()를 실행
*
* 결제 비용을 저장하는 money 멤버변수에 1박 가격인 55,000원 * 숙박일수(day)를 곱하여 저장
* 금액에 쉼표를 넣기위한 포맷을 money_s에 저장
*
* 결제비용과 결제완료 문구를 sleep으로 천천히 출력
*
* 매개변수인 hotelmoney에 결제비용을 더하여 저장 후
* hoelmoney를 return
* */
public int roomReservation_now(Scanner sc, int hotelmoney, DecimalFormat format, ArrayList<ReservationDay> arr2) {
in = Calendar.getInstance();
year = in.get(Calendar.YEAR);
month = in.get(Calendar.MONTH) + 1;
date = in.get(Calendar.DAY_OF_MONTH);
reser = sdf1.format(in.getTime());
format_s = sdf2.format(in.getTime());
datecheck(arr2);
guestSet(sc);
roomSet(sc, hotelmoney, format, arr2);
System.out.println();
System.out.println(" * 입력하신 정보 입니다.");
getInfo();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
money = 55000 * day;
money_s = format.format(money);
System.out.println();
System.out.println(" * " + day + "박 결제 비용은 " + money_s + "원 입니다. *");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println();
System.out.println(" * 결제되었습니다. 감사합니다. * ");
System.out.println();
hotelmoney += money;
return hotelmoney;
}
/* 날짜 지정 예약 메서드
*
* 오늘 날짜와 비교를 위한 now에 오늘 날짜 입력 후
* 날짜 비교를 위한 포맷인 sdf1으로 포맷하여 now_s에 저장
*
* 예약날짜를 8자리로 예약일 변수(reser)에 입력받음
* 만약 입력한 날짜가 8자리가 아니거나
* 연도, 월, 일이 이상하게 입력되거나
* 오늘 날짜(now_s)보다 이전으로 입력되면
* 오류 문구 출력 후 해당 메서드 다시 실행 후 return
*
* 체크인 변수(in)에 입력받은 날짜를 세팅
* 출력을 위한 포맷인 sdf2를 format_s에 저장
*
* 해당 날짜로 예약일 객체 확인 메서드 실행
* 고객정보 입력 메서드 실행
* 룸 예약 메서드 실행
* 각 메서드를 실행하여 나온 결과를 출력할 수 있도록 getInfo()를 실행
*
* 결제 비용을 저장하는 money 멤버변수에 1박 가격인 55,000원 * 숙박일수(day)를 곱하여 저장
* 금액에 쉼표를 넣기위한 포맷을 money_s에 저장
*
* 결제비용과 결제완료 문구를 sleep으로 천천히 출력
*
* 매개변수인 hotelmoney에 결제비용을 더하여 저장 후
* hoelmoney를 return
* */
public int roomReservation_later(Scanner sc, int hotelmoney, DecimalFormat format, ArrayList<ReservationDay> arr2) {
now = Calendar.getInstance();
String now_s = sdf1.format(now.getTime());
System.out.println();
System.out.print("* 예약 날짜를 입력해주세요(ex.20250101) : ");
reser = sc.nextLine();
if (reser.length() != 8) {
System.out.println();
System.out.println(" -- 잘못 입력하였습니다. 다시 입력해주세요. -- ");
roomReservation_later(sc, hotelmoney, format, arr2);
return hotelmoney;
}
datecheck(arr2);
year = Integer.parseInt(reser.substring(0, 4));
month = Integer.parseInt(reser.substring(4, 6));
date = Integer.parseInt(reser.substring(6));
if (year < 0 || month > 12 || date > 31) {
System.out.println();
System.out.println(" -- 잘못 입력하였습니다. 다시 입력해주세요. -- ");
roomReservation_later(sc, hotelmoney, format, arr2);
return hotelmoney;
} else if (Integer.parseInt(reser) < Integer.parseInt(now_s)) {
System.out.println();
System.out.println(" -- 예약일은 현재 날짜 이후로 해주세요. -- ");
roomReservation_later(sc, hotelmoney, format, arr2);
return hotelmoney;
}
in = Calendar.getInstance();
in.set(Calendar.YEAR, year);
in.set(Calendar.MONTH, month - 1);
in.set(Calendar.DAY_OF_MONTH, date);
format_s = sdf2.format(in.getTime());
guestSet(sc);
roomSet(sc, hotelmoney, format, arr2);
System.out.println();
System.out.println(" * 입력하신 정보 입니다.");
getInfo();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
money = 55000 * day;
money_s = format.format(money);
System.out.println();
System.out.println(" * " + day + "박 결제 비용은 " + money_s + "원 입니다. *");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println();
System.out.println(" * 결제되었습니다. 감사합니다. * ");
System.out.println();
return hotelmoney;
}
/* 정보 출력 메서드
*
* 체크아웃 날짜를 출력하기 위한 out 변수에 체크인 날짜를 입력 후
* 숙박일수(day)를 일수에 추가 후 출력을 위한 포맷인 sdf2로 format_e에 저장
*
* 입력된 정보들을 출력
* */
public void getInfo() {
out = Calendar.getInstance();
out.set(Calendar.YEAR, year);
out.set(Calendar.MONTH, month - 1);
out.set(Calendar.DAY_OF_MONTH, date);
out.add(Calendar.DAY_OF_MONTH, day);
format_e = sdf2.format(out.getTime());
System.out.println();
System.out.println(" * 고객 성함 : " + name);
System.out.println(" * 고객 성별 : " + (gender == 1 ? "남자" : "여자"));
System.out.println(" * 고객 나이 : " + age + "세");
System.out.println(" * 예약 룸 넘버 : " + room + "호");
System.out.println(" * 숙박 인원 : " + people + "명");
System.out.println(" * 숙박 일수 : " + day + "박 " + (day + 1) + "일");
System.out.println(" * 체크인 : " + format_s);
System.out.println(" * 체크아웃 : " + format_e);
}
/* 예약 취소 메서드
*
* 메서드 실행 시 환불을 할 때는 결제금액에 90%만 차감하므로
* money * 0.9를 하고 해당 금액을 쉼표 출력을 위해 format
*
* 취소를 동의할 시
*
* Calendar 클래스를 사용하여 체크인 날짜를 멤버변수 ing에 입력
* 이때 반복을 위한 변수인 z(0 ~ (day-1))를 일 수에 더해서 입력
* 당일, 당일 + 1, 당일 + 2....로 진행
*
* 날짜를 비교하기 위한 문자열 포맷(ex.20250101)으로 변환 후 reser_i에 저장
* 예약일 날짜 객체 모음(arr2)에 해당 날짜(reser_i)가 있다면
* 해당 날짜에 고객 객체에 저장되어 있는 키값인 room(호실)을 예약 종료(false)
* hotelmoney에 환불금을 차감하여 반환
* */
public int roomCancle(Scanner sc, int hotelmoney, DecimalFormat format, ArrayList<ReservationDay> arr2) {
try {
money_s = format.format(money * 0.9);
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * " + name + " 고객님의 예약취소를 도와드리겠습니다. *");
Thread.sleep(1500);
System.out.println(" * 취소수수료가 10% 부과되어 환불됩니다. * ");
Thread.sleep(1500);
System.out.println(" * 환불 금액은 " + money_s + "원 입니다. *");
Thread.sleep(1500);
} catch (InterruptedException e) {
}
System.out.println();
System.out.println(" * 취소하시겠습니까? * ");
System.out.print(" * Y/N : ");
String ny = sc.next();
if (ny.charAt(0) == 'Y' || ny.charAt(0) == 'y') {
hotelmoney -= (int) (money * 0.9);
name = "";
for (int i = 0; i < arr2.size(); i++) {
for (int z = 0; z < day; z++) {
ing = Calendar.getInstance();
ing.set(Calendar.YEAR, year);
ing.set(Calendar.MONTH, month - 1);
ing.set(Calendar.DAY_OF_MONTH, date + z);
String reser_i = sdf1.format(ing.getTime());
if (arr2.get(i).date.equals(reser_i)) {
arr2.get(i).map.put(room, false);
}
}
}
System.out.println();
System.out.println(" * " + room + "호실의 예약 취소가 완료되었습니다. *");
System.out.println(" * 감사합니다. * ");
room = 0;
} else if (ny.charAt(0) == 'N' || ny.charAt(0) == 'n') {
System.out.println();
System.out.println(" -- 고객님 요청으로 예약이 취소되지 않았습니다. --");
System.out.println(" -- 감사합니다. -- ");
} else {
System.out.println(" -- 잘못 입력하였습니다. -- ");
roomCancle(sc, hotelmoney, format, arr2);
return hotelmoney;
}
return hotelmoney;
}
/* 예약 연장 메서드
*
* 현재 예약 정보를 출력한 뒤
* 연장할 숙박일수를 입력받아 기존의 숙박일수(day)에 더해서 저장
*
* 예약일 연박 생성 메서드를 실행하여
* 추가된 숙박일수를 기준으로 다시 예약 과정 진행
*
* 추가비용 안내 후 55,000원에 추가 숙박일수를 곱한 값을
* hotelmoney에 더하여 저장 후 반환
*
* */
public int roomReservationChange(Scanner sc, int hotelmoney, DecimalFormat format, ArrayList<ReservationDay> arr2) {
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 고객님의 예약 정보 입니다.");
System.out.println();
System.out.println(" * 숙박 일수 : " + day + "박 " + (day + 1) + "일");
System.out.println(" * 체크인 : " + format_s);
System.out.println(" * 체크아웃 : " + format_e);
System.out.println();
System.out.print(" * 몇 박을 연장하시겠습니까? : ");
int day_c = sc.nextInt();
int money_c = 55000 * day_c;
day += day_c;
money_s = format.format(money_c);
System.out.println();
System.out.println(" * " + day_c + "박 추가 결제 비용은 " + money_s + "원 입니다. *");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
System.out.println();
System.out.println(" * 결제되었습니다. 감사합니다. * ");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
}
out.set(Calendar.YEAR, year);
out.set(Calendar.MONTH, month - 1);
out.set(Calendar.DAY_OF_MONTH, date);
out.add(Calendar.DAY_OF_MONTH, day);
format_e = sdf2.format(out.getTime());
roomcheck(arr2);
System.out.println();
System.out.println(" * 변경된 예약정보 입니다.");
System.out.println();
System.out.println(" * 숙박 일수 : " + day + "박 " + (day + 1) + "일");
System.out.println(" * 체크인 : " + format_s);
System.out.println(" * 체크아웃 : " + format_e);
hotelmoney += money_c;
return hotelmoney;
}
}
ReservationDay 클래스
- 호텔의 예약일과 방의 예약 현황을 관리할 수 있는 클래스이다.
코드
package ReservationSystem;
import java.util.HashMap;
public class ReservationDay {
String date;
HashMap<Integer, Boolean> map;
/* ReservationDay 생성자 메서드
*
* 생성과 동시에 해쉬맵인 map안에 101~303호의 호실 데이터를
* false(빈방)으로 세팅한다.
*
* */
public ReservationDay() {
date="";
map = new HashMap<Integer, Boolean>();
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
map.put((i * 100) + j, false);
}
}
}
}
Main 클래스
- Main 메서드를 가지고 있는 클래스이며 주요 기능들이 실행된다.
주요 메서드
- printMenu() - 기본 메뉴 출력 메서드
- search() - 고객 검색 메서드
- change() - 예약 정보 변경 메서드
- getRoomInfo() - 예약 현황 조회 메서드
- getHoterInfo() - 영업 현황 조회 메서드
코드
package ReservationSystem;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.InputMismatchException;
import java.util.Iterator;
import java.util.Scanner;
public class ReservationMain {
/* 기본 메뉴 출력 메서드
*
* Thread.sleep()을 이용하여
* 타이틀과 입력 메뉴에 출력 격차를 주어
* 로딩처럼 화면 구현
* */
public static void printMenu() {
System.out.println(" ________________________________________________");
System.out.println("| ___ ___ _____ __ __ |");
System.out.println("| / __\\ /\\ /\\ /\\ /\\/___\\/__ \\/__\\/ / |");
System.out.println("| / / / /_/ / / /_/ // // / /\\/_\\ / / |");
System.out.println("| / /___/ __ / / __ / \\_// / / //__/ /___ |");
System.out.println("| \\____/\\/ /_/ \\/ /_/\\___/ \\/ \\__/\\____/ |");
System.out.println("|________________________________________________|");
System.out.println();
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("==================================================");
System.out.println();
System.out.println(" * CH 호텔 예약 시스템 *");
System.out.println(" * CH Hotel Reservation System *");
System.out.println(" * 1 Day 55,000won *");
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 1. 룸 예약하기");
System.out.println(" * 2. 고객 검색");
System.out.println(" * 3. 룸 예약 현황");
System.out.println(" * 4. 영업 현황 확인 ");
System.out.println(" * 5. 프로그램 종료");
System.out.println();
System.out.print(" * 메뉴 입력 : ");
}
/* 메인메뉴 - 2
* 고객 검색 메서드
*
* 입력받은 고객명을 현재 고객 객체(arr)수 만큼 반복하여
* 해당 고객이 몇 명이 있는지 cnt로 카운팅 (동명이인 체크)
*
* 다시 cnt를 0으로 초기화 한 뒤
* 고객 객체 수만큼 입력받은 고객명을 비교하여 고객정보 출력
* cnt로 카운팅 된 번호를 고객 객체에 저장하여 몇 번째 고객인지 구분
*
* 동명이인이 있다면 몇 번째 고객을 찾는건지 입력을 받은 뒤
* 고객 객체들 중 입력된 고객 이름이 똑같고 저장된 고객 번호(search)가 같으면
* 해당 고객의 정보만 출력 후 해당 고객의 ArrayList 인덱스를 반환
* */
public static int search(Scanner sc, ArrayList<Guest> arr, int hotelmoney) {
int cnt = 0;
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.print(" * 고객명을 입력하세요 : ");
String guest = sc.nextLine();
int room_n = -1;
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).name.equals(guest)) {
cnt++;
}
}
System.out.println();
System.out.println(" * " + cnt + "건의 예약이 검색되었습니다. *");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
cnt = 0;
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).name.equals(guest)) {
cnt++;
System.out.println();
System.out.println(" ==== " + (cnt) + "번째 고객 ====");
arr.get(i).search = cnt;
arr.get(i).getInfo();
room_n = i;
}
}
if (cnt >= 2) {
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" -- 동명이인이 있습니다. -- ");
System.out.println();
System.out.print(" * 몇 번째 고객을 검색할까요? : ");
int num = sc.nextInt();
sc.nextLine();
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).name.equals(guest) && arr.get(i).search == num) {
System.out.println();
System.out.println(" * " + num + "번째 고객입니다. *");
arr.get(i).getInfo();
room_n = i;
}
}
}
return room_n;
}
/* 예약 정보 변경 메서드
*
* 고객 검색 메서드로 찾은 고객데이터가 들어있는 arr의 인덱스(room_n)로
* 취소와 연장을 결정할 수 있는 메뉴 출력
*
* 취소 시
* 예약 취소 메서드 실행
*
* 연장 시
* 예약 연장 메서드 실행
*
* 3번을 입력 시 이전 메뉴로 이동
*
* 취소하거나 연장에서 변경된 hotelmoney를 반환
*
* */
public static int change(Scanner sc, ArrayList<Guest> arr, int hotelmoney, int room_n, DecimalFormat format,
ArrayList<ReservationDay> arr2) {
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 1. 예약 취소 ");
System.out.println(" * 2. 예약 연장");
System.out.println(" * 3. 이전 메뉴");
System.out.println();
System.out.print(" * 메뉴 입력 : ");
int user2 = sc.nextInt();
try {
switch (user2) {
case 1:
hotelmoney = arr.get(room_n).roomCancle(sc, hotelmoney, format, arr2);
break;
case 2:
hotelmoney = arr.get(room_n).roomReservationChange(sc, hotelmoney, format, arr2);
break;
case 3:
System.out.println(" * 이전 메뉴로 돌아갑니다. * ");
break;
default:
System.out.println(" -- 잘못 입력하였습니다. -- ");
}
} catch (IndexOutOfBoundsException e) {
System.out.println();
System.out.println(" -- 예약한 고객이 없습니다. -- ");
}
return hotelmoney;
}
/* 예약 현황 메서드
*
* 예약일 정보가 들어있는 arr2 안에 있는 해쉬맵의 키 값을 추출하여 key에 저장
* 오늘 날짜를 담고 있는 today 변수를 만들고 모든 호실을 체크할 수 있는 반복문을 이용
* 그 반복문 안에서 모든 고객 정보를 확인하는 반복문을 이용하여
* today의 내용과 해당 고객의 예약일이 같고 지금 확인하는 호실 정보가 같다면
* 빈방인지 체크하는 check 변수를 true로 바꾸고 현재 이용중으로 표시
* 만약 모든 고객을 확인하였는데도 check가 false라면 현재 빈방으로 표시
*
* 오늘의 예약정보를 확인 후 이번에는 모든 고객 정보를 확인하되
* 예약일 정보가 today와 같지 않고 호실 정보가 같으면 예약중으로 표시
*
* */
public static void getRoomInfo(ArrayList<Guest> arr, ArrayList<ReservationDay> arr2) {
Iterator<Integer> keys = arr2.get(0).map.keySet().iterator();
ArrayList<Integer> key = new ArrayList<Integer>();
Calendar now = Calendar.getInstance();
boolean check = false;
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
String today = sdf1.format(now.getTime());
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" *** 호텔 룸 예약 현황 *** ");
System.out.println();
while (keys.hasNext()) {
key.add(keys.next());
}
for (int i = 0; i < key.size(); i++) {
System.out.println();
System.out.println(" *** " + key.get(i) + "호실 ***");
System.out.println("--------------------------------------------------");
for (int j = 0; j < arr.size(); j++) {
check = false;
if (arr.get(j).reser.equals(today) && arr.get(j).room == key.get(i)) {
System.out.println(" * 현재 이용 중 * ");
System.out.println();
System.out.println(" * 고객 성함 : " + arr.get(j).name);
System.out.println(" * 숙박 인원 : " + arr.get(j).people + "명");
System.out.println(" * 체크인 : " + arr.get(j).format_s);
System.out.println(" * 체크아웃 : " + arr.get(j).format_e);
System.out.println();
check = true;
break;
}
}
if (!check) {
System.out.println(" -- 현재 빈방 -- ");
System.out.println();
}
for (int j = 0; j < arr.size(); j++) {
if (!(arr.get(j).reser.equals(today)) && arr.get(j).room == key.get(i)) {
System.out.println(" * 예약자 * ");
System.out.println();
System.out.println(" * 고객 성함 : " + arr.get(j).name);
System.out.println(" * 숙박 인원 : " + arr.get(j).people + "명");
System.out.println(" * 체크인 : " + arr.get(j).format_s);
System.out.println(" * 체크아웃 : " + arr.get(j).format_e);
System.out.println();
}
}
}
}
/* 영업 현황 메서드
*
* 오늘 날짜를 담고 있는 today 변수 생성
*
* 예약일을 모음인 arr2를 모두 확인하여 오늘 날짜의 예약정보를 찾고
* 해당 날짜에 룸 예약수를 카운트 하여 count_room(현재 이용 고객)을 생성
*
* visit(방문객 수)는 고객 객체를 생성할 때 마다 +1하여 저장
*
* 현재 이용 고객과 방문객 수 그리고 매출을 출력
*
* */
public static void getHotelInfo(ArrayList<Guest> arr, ArrayList<ReservationDay> arr2, DecimalFormat format,
int hotelmoney, int visit) {
int count_room = 0;
Calendar now = Calendar.getInstance();
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
String today = sdf1.format(now.getTime());
for (int i = 0; i < arr2.size(); i++) {
if (arr2.get(i).date.equals(today)) {
for (int j = 101; j <= 303; j++) {
if (arr2.get(i).map.get(j)) {
count_room++;
}
if (j % 100 == 3) {
j += 97;
}
}
break;
}
}
String hotelmoney_s = format.format(hotelmoney);
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 현재 영업 현황 * ");
System.out.println();
System.out.println(" * 현재 이용 고객 수 : " + count_room + "명");
System.out.println(" * 누적 방문 고객 수 : " + visit + "명");
System.out.println(" * 누적 매출액 : " + format.format(hotelmoney - 100000) + "원");
System.out.println(" * 현재 금고 잔액 : " + hotelmoney_s + "원");
System.out.println();
}
public static void main(String[] args) {
ArrayList<Guest> arr = new ArrayList<Guest>();
ArrayList<ReservationDay> arr2 = new ArrayList<ReservationDay>();
arr2.add(new ReservationDay());
DecimalFormat format = new DecimalFormat("#,###");
int hotelmoney = 100000;
int visit = 0;
while (true) {
Scanner sc = new Scanner(System.in);
try {
printMenu();
int user = sc.nextInt();
sc.nextLine();
switch (user) {
case 1:
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 1. 오늘 예약");
System.out.println(" * 2. 예약일 지정 ");
System.out.println(" * 3. 이전 메뉴");
System.out.println();
System.out.print(" * 메뉴 입력 : ");
int user_a = sc.nextInt();
sc.nextLine();
switch (user_a) {
case 1:
arr.add(new Guest());
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 오늘 예약 * ");
hotelmoney = arr.get(arr.size() - 1).roomReservation_now(sc, hotelmoney, format, arr2);
visit++;
break;
case 2:
arr.add(new Guest());
System.out.println();
System.out.println("--------------------------------------------------");
System.out.println();
System.out.println(" * 예약일 지정 * ");
hotelmoney = arr.get(arr.size() - 1).roomReservation_later(sc, hotelmoney, format, arr2);
visit++;
break;
case 3:
System.out.println();
System.out.println(" * 이전 메뉴로 돌아갑니다. * ");
break;
default:
System.out.println();
System.out.println(" * 잘못 입력하였습니다. * ");
}
break;
case 2:
int room_n = search(sc, arr, hotelmoney);
if (room_n == -1) {
System.out.println();
System.out.println(" -- 해당 고객명으로 예약한 방이 없습니다. --");
continue;
}
hotelmoney = change(sc, arr, hotelmoney, room_n, format, arr2);
break;
case 3:
getRoomInfo(arr, arr2);
break;
case 4:
getHotelInfo(arr, arr2, format, hotelmoney, visit);
break;
case 5:
System.out.println();
System.out.println(" -- 프로그램을 종료합니다. -- ");
System.exit(0);
break;
default:
System.out.println();
System.out.println(" -- 잘못 입력하였습니다. -- ");
}
} catch (InputMismatchException e) {
System.out.println();
System.out.println(" -- 잘못 입력하였습니다. -- ");
System.out.println(" -- 메뉴로 돌아갑니다. --");
} catch (NullPointerException e) {
System.out.println();
System.out.println(" -- 방 번호를 잘못 입력하였습니다. -- ");
System.out.println(" -- 메뉴로 돌아갑니다. --");
} catch (Exception e) {
System.out.println();
System.out.println(" -- 알 수 없는 오류가 발생하였습니다. -- ");
System.out.println(" -- 고객센터에 문의하여 주십시오. -- ");
}
}
}
}
실행화면
메인 화면
- 아스키 코드로 메인 화면을 꾸미고 1~5를 입력하여 메뉴에 진입

오늘 예약
- 오늘 예약을 선택 시 고객정보를 입력 하여 예약을 진행한다.
- 원하는 호실을 입력 후 자동 결제가 이루어지고 랜덤 배정 시 비어있는 방으로 랜덤 배정된다.


예약일 지정 예약
- 예약일 지정을 선택 시 예약날짜를 입력하여 해당 날짜로 예약하게 된다.


고객 검색
- 고객명을 입력하여 해당 고객의 정보를 조회하고 취소 또는 연장이 가능하다.
- 동명이인이 있을 시 해당 이름으로된 모든 고객을 표시하고 몇번째 고객에 대한 수정이 필요한지 물어본다.


호텔 예약 현황
- 호텔의 룸마다 예약 현황을 보여준다.
- 현재 이용중, 현재 빈방, 예약중으로 구분하여 표시


영업 현황
- 현재까지의 영업 현황을 보여준다.
- 기존 금액을 100,000원으로 세팅하여 매출액과 잔고를 따로 구분하여 표시한다.
- 현재 이용 고객수는 오늘 날짜의 이용고객이고 누적 방문 고객수는 총 예약자 수이다.

프로젝트 느낀점
해당 프로젝트를 혼자서 진행하고 정말 많은 고민과 시행착오를 겪었던 것 같다.
고객의 정보를 받으려면 해당 고객마다의 정보가 각각 존재해야하니 객체를 사용하고.. 그걸 모아놓은 집합이 필요하고..
예약일을 지정하는 등의 실제 호텔에서 필요할 다양한 기능을 구현하려고 노력했었던 것 같다.
중간쯤까지 만들고 나니 연박을 할 시 해당 중간에 해당하는 날짜들에는 예약중으로 되어야하고..
고객을 검색 시 동명이인 문제 등 완성됐다고 생각했던 시기에도
아직 많은 문제가 남았구나 하면서 더 고민했었던 것 같다. (아마 아직도 내가 발견하지 못한 오류가 있을 것 같다는 생각도 든다.)
정말 프로그램에 완성은 없구나란 생각도 들었고 다양한 문제에 부딫히니 더욱 성장한다는 생각도 들었다.
글을 쓰는 지금 시점에서는 이미 데이터 베이스 수업을 들어서 이렇게 고생하며 기능을 만들 필요는 없게 되었지만
오히려 자바의 객체 지향에 대해 더욱 활용해보고 이해하는 시간이 되었던 것 같다.
그리고 제일 중요한건 내가 설계하고 내가 만든 프로그램이라 그런지
정말 재밌게 시간을 보내며 고민하고 만들었다는 생각에 매우 뿌듯했다.
다음에는 데이터베이스를 활용하여 더욱 그럴싸한 미니 프로젝트를 해보려고 한다.
'개발 > JAVA' 카테고리의 다른 글
[JAVA/자바] 배열과 리스트 (1) | 2025.01.18 |
---|---|
[JAVA/자바] StringTokenizer 문자열 분리 (1) | 2024.12.28 |
[JAVA/자바] Scanner와 BufferedReader의 차이 (2) | 2024.12.21 |