2023. 10. 27. 17:56ㆍJava/project
- System.out.println()형태로 호텔 예약 프로그램을 만듭니다.
- UUID, LocalDateTime, LocalDate 사용
변경 사항
- 블랙리스트 패턴이 필요없음으로 삭제
- ViewManagement.java에서 난잡하게 출력했던 출력문을 HotelReservationApp reservationProcess()로 정리
- 객체 지향적 관점에서 각각의 객체의 역할을 부여하고 이에 해당하는 메서드 정리
모든 코드 페이지의 전문을 보고 싶다면 링크 달아놓겠습니다.
https://github.com/Kminss/hotel-reservation-project
GitHub - Kminss/hotel-reservation-project: 내배캠 호텔 예약 시스템 팀 프로젝트
내배캠 호텔 예약 시스템 팀 프로젝트. Contribute to Kminss/hotel-reservation-project development by creating an account on GitHub.
github.com
맡은 역할 : 예약 프로세스
- 역할에 해당하는 코드만 적어놓을 것이며 팀원들이 적은 코드는 해당 윗 링크에 존재합니다.
- 예시로 InputManager.java(Sacnner 입출력 관리)는 제외시켰습니다.
1. ViewManagement.java
- 해당 페이지는 관리 페이지임으로 출력문을 이동했습니다.
- 해당 페이지는 예약 프로세스에 관련 없는 코드라 생략합니다.(전문 참고)
package com.nbc.hotel.model;
import java.util.List;
public class ViewManagement {
public static void showFindReservationMenu() {
System.out.println();
System.out.println("객실 예약 조회 화면입니다.");
System.out.println("1. 모든 예약 조회(관리자 기능)");
System.out.println("2. 내 예약 목록 조회");
System.out.println("3. 예약 번호로 조회");
System.out.println("4. 돌아가기");
System.out.print("입력: ");
}
public static void showFindAllReservations(List<Reservation> reservations) {
System.out.println("모든 예약을 조회합니다.");
showReservations(reservations);
}
public static void showFindMyReservations(List<Reservation> reservations) {
System.out.println("내 예약 목록을 조회합니다.");
showReservations(reservations);
}
public static void showFindReservation() {
System.out.println("예약 번호로 조회합니다.");
System.out.println("예약 번호를 입력해주세요.");
}
public static void showReservations(List<Reservation> reservations) {
System.out.println("[예약 정보]");
reservations.forEach(reservation -> System.out.println(reservation.getReservationInfo()));
}
public static void showFindReservationClose() {
System.out.println("예약 조회를 종료합니다.");
}
public static void showFindReservationFailed() {
System.out.println("예약 번호로 조회할 수 없습니다.");
}
public static void showCancelReservation() {
System.out.println("========예약 취소하기========");
System.out.println("취소하실 객실의 예약 번호를 입력해주세요.");
System.out.print("입력 > ");
}
public static void showCancelReservationSuccess(Reservation reservation) {
System.out.println("===========success===========");
System.out.println("객실 예약이 취소 되었습니다.");
System.out.println("===========예약정보===========");
System.out.println("==============================");
System.out.printf(reservation.getReservationInfo());
}
public static void showCancelReservationFailed(String reason) {
System.out.println("===========fail===========");
System.out.println("객실 예약 취소가 실패하였습니다.");
System.out.println("===========사유===========");
System.out.println(reason);
System.out.println("==========================");
}
}
2. Reservation.java
- LocalDate reservationDate // 예약 날짜
- LocalDateTime reservationDate2 // 예약 당일
- 이전에 사용했던 메서드 hasMoney()등등은 Reservation.java에서 이루어지지 않도록 변경했습니다.
package com.nbc.hotel.model;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
public class Reservation {
private UUID uuid;
private Room room;
private String customerName;
private String customerPhoneNumber;
private LocalDateTime reservationDate;
public Reservation(UUID uuid, Room room, String customerName, String customerPhoneNumber, LocalDateTime reservationDate) {
this.uuid = uuid;
this.room = room;
this.customerName = customerName;
this.customerPhoneNumber = customerPhoneNumber;
this.reservationDate = reservationDate;
}
public UUID getUuid() {
return uuid;
}
public String getReservationInfo () {
return String.format("예약일: %s %n예약번호: %s %n %s 예약자 명: %s %n예약자 휴대폰번호: %s %n",
reservationDate.format(DateTimeFormatter.ISO_DATE),
uuid,
room.getRoomInfo(),
customerName,
customerPhoneNumber);
}
public UUID getReservationId () {
return uuid;
}
}
3. Room.java
- getInfo()추가
package com.nbc.hotel.model;
import java.util.List;
public class Room {
Double size;
Double price;
List<Reservation> reservations;
public Room(Double size, Double price) {
this.size = size;
this.price = price;
}
public Double getSize() {
return size;
}
public Double getPrice() {
return price;
}
public String getRoomInfo() {
return String.format("객실 크기: %.1f %n 객실 금액: %.1f %n", size, price);
}
}
4. Customer.java
- 출력문에 필요없는 getter, setter정리
package com.nbc.hotel.model;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Customer extends User{
private String name;
private String phoneNumber;
private Double money;
private List<UUID> reservationIds;
public Customer(String name, String phoneNumber, Double money) {
this.name = name;
this.phoneNumber = phoneNumber;
this.money = money;
this.reservationIds = new ArrayList<>();
}
public Customer(String name, String phoneNumber, Double money, List<UUID> reservationIds) {
this(name, phoneNumber, money);
this.reservationIds = reservationIds;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public Double getMoney() {
return money;
}
public List<UUID> getReservationIds() {
return reservationIds;
}
}
5. Hotel.java
- 블랙리스트 패턴 삭제
- checkBlackListPhoneNumber(), checkCustomerName(), checkMoeny()
- Hotel.java에서 이루어지는 기존 메서드들 삭제
- 예약조회, 모든 예약 조회 메서드
package com.nbc.hotel.model;
import com.nbc.hotel.exception.ReservationNotFoundException;
import java.util.ArrayList;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Hotel {
private List<Room> rooms;
private List<Reservation> reservations = new ArrayList<>();
private Double money;
Boolean cancelReservations;
public void cancelReservation(Reservation targetReservation) throws ReservationNotFoundException {
if (!reservations.remove(targetReservation)) {
throw new ReservationNotFoundException();
}
}
/**
* 예약이 존재하면 예약을 돌려주고, 없다면 ReservationNotFoundException 던진다
*
* @param reservationId
* @return
*/
public Reservation findReservationByUUID(UUID reservationId) {
return reservations
.stream()
.filter(reservation -> reservation.getReservationId().compareTo(reservationId) == 0)
.findFirst()
.orElseThrow(ReservationNotFoundException::new);
}
public List<Reservation> findAllReservations() {
return reservations;
}
/**
* @param uuids
* @return
*/
public List<Reservation> findReservationsByUUIDs(List<UUID> uuids) {
return reservations
.stream()
.filter(reservation -> uuids.contains(reservation.getUuid()))
.toList();
}
}
6. HotelReservationApp.java
- 모든 입,출력단을 HotelReservationApp에서 관리
- 예약, 예약 조회, 예약 취서 프로세스 관련 메서드들을 가집니다.
- 이에 대한 메서드 설명은 주석 처리해놨습니다.
package com.nbc.hotel.app;
import com.nbc.hotel.exception.ReservationNotFoundException;
import com.nbc.hotel.model.*;
import com.nbc.hotel.util.Util;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import static com.nbc.hotel.model.ViewManagement.showReservationInfo;
import static com.nbc.hotel.model.ViewManagement.showSelectedDateRooms;
import static com.nbc.hotel.util.Util.isValidDate;
public class HotelReservationApp {
private Hotel hotel;
private Customer customer;
public HotelReservationApp(Customer customer) {
hotel = new Hotel();
this.customer = customer;
}
public void mainProcess() {
while (true) {
try {
System.out.println("호텔 기능을 선택해주세요. ");
System.out.println("1. 예약 2. 취소 3. 조회");
int select = InputManager.inputMenuNumber(3);
switch (select) {
case 0:
reservationProcess();
break;
case 1:
// 예약 취소
cancelReservationProcess();
break;
case 2:
// 예약 조회
findReservationProcess();
break;
default:
System.out.println("잘못된 입력입니다. 다시 시도해주세요");
break;
}
} catch (Exception e) {
System.out.println("오류가 발생했습니다. " + e.getMessage());
}
}
}
private void reservationProcess() throws Exception {
// 입력단 예외 상황 해결을 위해 makeReservation()으로 옮김
System.out.println("날짜를 입력해주세요 : ");
String selectDate = InputManager.handleInput();
makeReservation(selectDate);
// 날짜 입력 로직
System.out.println("============================");
System.out.println("선택하고 싶은 방을 골라주세요 : ");
int selectRoomNumber = InputManager.inputMenuNumber(hotel.getRooms().size());
// room 확인 및 예약 진행 로직
// 이미 예약된 방인지 검증
if (isReserved(selectDate, selectRoomNumber))
throw new Exception("이미 예약된 방입니다.");
System.out.println("=====1. 예약하기 2. 취소하기=====");
int finalCheck = InputManager.inputMenuNumber(2);
ViewManagement.showReservationOrCancel(finalCheck);
// 해당 사항으로 최종확인 여부를 물음
System.out.println("예약자 성함을 알려주세요 : ");
String customerName = InputManager.handleInput();
hotel.checkCustomerName(customerName);
// 예약자 이름 확인 로직
System.out.println("예약자 전화번호를 입력해주세요 : (01*-****-****만 가능)");
String customerPhoneNumber = InputManager.handleInput();
boolean isValidPhoneNumber = hotel.checkPhoneNumber(customerPhoneNumber);
if (!isValidPhoneNumber) {
throw new Exception("올바르지 않은 전화번호입니다.");
} else {
double selectRoomPrice = hotel.getRooms().get(selectRoomNumber).getPrice();
if (hotel.checkMoney(customer, selectRoomPrice)) {
finalReservation(selectDate, selectRoomNumber,
customerName, customerPhoneNumber);
}
}
}
public void finalReservation(String selectDate, int selectRoomNumber, String customerName,
String customerPhoneNumber) {
Reservation reservation = new Reservation(UUID.randomUUID(),
hotel.getRooms().get(selectRoomNumber), customerName,
customerPhoneNumber, LocalDate.parse(selectDate), LocalDateTime.now());
hotel.getRooms().get(selectRoomNumber).addReservation(reservation);
System.out.println(customerName + "님 예약 완료되셨습니다.");
System.out.println(customerName + "님 예약 번호는" + reservation.getUUID() + "입니다.");
hotel.getReservations().add(reservation);
showReservationInfo(reservation);
}
private boolean isReserved(String selectDate, int selectRoomNumber) {
return hotel.getRooms().get(selectRoomNumber).isReserved(LocalDate.parse(selectDate));
}
public void makeReservation(String selectDate) throws Exception {
try {
// selectDate의 유효성을 검사합니다.
if (!isValidDate(selectDate)) {
// 만약 날짜를 파싱해서 제대로된 yyyy-MM-dd가 들어가지 않을때
throw new IllegalArgumentException("유효하지 않은 날짜 형식입니다.");
}
} catch (IllegalArgumentException e) {
System.out.println("예외 발생: " + e.getMessage());
System.out.println("=========다시 실행합니다=========");
throw new Exception();
}
showSelectedDateRooms(selectDate, hotel.getRooms());
}
/**
* 예약 조회 컨트롤 메서드
*/
public void findReservationProcess() {
ViewManagement.showFindReservationMenu();
Integer menuNumber = InputManager.inputMenuNumber(4);
switch (FindMenu.toMenu(menuNumber)) {
case FIND_ALL -> findAllReservationsProcess();
case FIND_OWN -> findOwnReservationsProcess();
case FIND_UUID -> findOneReservationProcess();
case QUIT -> findReservationQuitProcess();
}
}
public void findAllReservationsProcess() {
List<Reservation> allReservations = hotel.findAllReservations();
ViewManagement.showFindAllReservations(allReservations);
}
public void findOwnReservationsProcess() {
List<Reservation> reservations = hotel.findReservationsByUUIDs(customer.getReservationIds());
ViewManagement.showFindMyReservations(reservations);
}
public void findOneReservationProcess() {
ViewManagement.showFindReservation(); // 메뉴 출력
try {
UUID uuid = InputManager.inputUUID(); // 입력 받음
Reservation reservation = hotel.findReservationByUUID(uuid); // 찾음
ViewManagement.showReservations(List.of(reservation)); // 출력
} catch (ReservationNotFoundException exception) {
System.out.println("잘못된 UUID 입력입니다.");
}
}
public void findReservationQuitProcess() {
ViewManagement.showFindReservationClose();
}
public void cancelReservationProcess() {
ViewManagement.showCancelReservation();
String reservationId = InputManager.handleInput();
try {
Reservation reservation = hotel.findReservationByUUID(Util.converStringToUuid(reservationId));
hotel.cancelReservation(reservation);
ViewManagement.showCancelReservationSuccess(reservation);
mainProcess();
} catch (ReservationNotFoundException exception) {
ViewManagement.showCancelReservationFailed(exception.getMessage());
}
}
}
-예약 화면 예시
호텔을 예약하시겠습니까?
1. 예약 2. 취소 3. 조회
1
날짜를 입력해주세요 :
2023-11-23
============================
해당 날짜 : 2023-11-23 방 예약
============================
1. size: 1 price: $90.0
2. size: 1 price: $110.0
3. size: 1 price: $130.0
4. size: 1 price: $190.0
5. size: 2 price: $140.0
6. size: 2 price: $160.0
7. size: 2 price: $200.0
8. size: 2 price: $220.0
============================
선택하고 싶은 방을 골라주세요 :
5
======해당 방이 맞으십니까?======
=========2023-11-23=========
size : 2 price : $140.0
=====1. 예약하기 2. 취소하기=====
1
예약자 성함을 알려주세요 :
papa
예약자 전화번호를 입력해주세요 :
010-2222-3333
papa님 예약 완료되셨습니다.
papa님 예약 번호는 1입니다.
================================
name : papa
phoneNumber : 010-2222-3333
reservationId : 1
reservationDate : 2023-11-23
reservationDate2 : 2023-11-23
reservationUUID : f3d268a8-d64b-45cd-b8ad-46704659b489
reservationPrice : 140.0
roomSize : 2.0
================================
프로젝트 아쉬웠던 점
1. 요구사항 파악 :
전화번호 제한 정규표현식(01*-****-****)을 착각해서 블랙리스트 패턴을 만들라고 생각했다....
좀 제대로 읽어보는 걸로... ㅎㅎ
2. 객체 지향적 관점 :
코드 전문을 빠르게 만들어 올리는 것을 주력으로 해 ViewMangement쪽에 출력문을 다 넣어놨는데
팀원들이 싱글톤 및 메모리 관련 측면에서 설계를 하다보니 많이 배웠습니다.
객체 지향적 관점에 대해서 따로 공부해 봐야겠다는 생각을 듭니다.
3. 협업툴 (Git) :
사용한다고 사용했는데 pull request라든지 merge과정을 팀원들한테 물어보면서 했습니다.
이 과정에서 merge하는데 저의 branch에서 만든 코드와 main branch의 merge과정이 계속 안되어서
시간을 좀 오래 썼다는점...?이 아쉬웠습니다.(팀원분들 너무 감사합니다...)
'Java > project' 카테고리의 다른 글
호텔 예약 프로그램(2) (1) | 2023.10.26 |
---|---|
호텔 예약 프로그램(1) (0) | 2023.10.24 |
[JAVA] 키오스크 만들기(2일차) (1) | 2023.10.19 |
[JAVA] 키오스크 만들기(1일차) (0) | 2023.10.18 |