이번 자바 팀프로젝트는 호텔 예약 프로그램 작성이다. 필수 구현 요구사항은 다음과 같다.
- 호텔은 여러 객실, 보유 자산을 가지고 있다.
- 객실은 객실 당 하루에 한 사람만 예약이 가능하다.
- 객실은 크기, 숙박비를 가진다.
- 예약은 객실, 고객의 이름, 고객의 전화번호, 예약 날짜를 가지고 있다.
- 전화 번호 제한(XXX-XXXX-XXXX) 정규 표현식 (선택)
- 예약 날짜 ****
- 날짜는 ISO 8601 형식으로 조합된 UTC 날짜 및 시간 예) 2016-10-27T17:13:40+00:00
- 고객은 이름, 전화번호, 소지금을 가진다.
- 고객 소지금보다 비싼 방은 예약 불가
- 호텔은 모든 예약 목록을 조회 할 수 있다.
- 고객은 자신의 예약 목록을 조회 할 수 있다.
- 예약 번호로 예약 내역을 조회한다
- 고객은 자신의 예약을 취소 할 수 있다.
- 고객이 호텔 예약 시에 예약 번호(id)를 반환 (uuid 활용)
- 고객이 호텔 예약에 성공하면 예약 번호(id)를 받는다.
- 고객이 예약 목록을 조회 시 예약 번호도 같이 조회 된다.
- 고객이 예약 취소 시 예약 번호를 통해 자신의 특정 예약을 취소한다
[처음] 나의 설계는 다음과 같았다. 기본적인 이 프로그램의 중요 흐름은 이것이다.
손님 입장 : 자신의 정보 입력(이름, 전화번호, 예산) -> 예약할 날짜 선택 -> 해당 날짜 예약 가능한 방 조회 ->
예약 하고 싶은 방 선택 -> 예약 조건이 만족하면 예약성공 -> uuid 출력
이다. 이런 흐름을 갖는 프로그램을 갖기 위해서 클래스를 5가지로 나누었다. 호텔의 전반적인 기능을 가져야할 호텔 클래스, 방의 정보(방 호수, 방 가격 등 방의 정보 , 예약 가능 여부)를 갖고 있어야 할 방 클래스, 손님의 정보를 가져야할 손님 클래스, 예약에 관한 모든 업무가 포함되어 있는 예약 클래스, 사용자가 볼 수 있는 화면을 출력하고 컨트롤 해줄 뷰 클래스
이렇게 5가지의 클래스를 갖는 프로그램을 설계 했다.
호텔 클래스에는 호텔의 자산을 갖는 변수와 전체 예약이 저장된 자료구조가 필요했다. 전체 예약이 저장된 자료구조는 map이 적절하다고 생각했다. key값을 uuid로 갖고, value값을 예약 객체를 받으면 된다. 후에 설명하겠지만, 예약 객체 안에는 손님 객체, 방 객체가 포함되어 있으므로 value값에 예약 정보 확인에 필요한 모든 정보가 들어간다. 또한 호텔은 예약 확인, 예약 삭제 메소드를 가져야한다. 객체지향적 관점에서봤을 때 예약을 관리하는 주체는 호텔이기 때문.
예약확인 메소드는 두가진데, uuid를 통해 손님 한명이 예약확인 하는경우와 전체 예약조회다. 둘다map의 조회 방식을 쓰면 간단히 구현된다. 예약 삭제는 map의 remove()메소드를 통해 예약을 지워주면 끝!
방 클래스에는 방 크기/방 가격/ 방 호수 세가지 기본 변수와 Date 타입을 갖는 ArrayList를 갖도록 했다. ArrrayList를 방 클래스가 갖는 이유는 월요일의 101호와 화요일의 101호는 날짜만 달라지므로서 2개의 상품으로 인식할 수 있기 때문이다. 방이갖고 있는 모든 정보는 동일하지만, 날짜가 다르다면, 이 방은 상품으로서 각각 존재한다. 따라서 판매대에 올릴때에는두개의 객체로 존재해야한다. 하지만, 날짜만 구분해준다면 객체를 2개를 생성하는 것이아닌, ArrayList의 인덱스값으로 두개의 상품을 치환해서 생각하면 된다. 또한 방이 가져야할 메소드는 방이 해당 날짜에 예약이 가능한지 판단해주는 메소드이다. 이는 date 변수를 담고 있는 ArrayList에 해당날짜의 값이 존재하는지 판단해서 T/F로 반환해주면 된다. 방식은 if문에 조건으로 contains(해당날짜) 메소드를 이용하면 된다.
손님 클래스에는 손님의 정보들(이름, 전화번호, 소지금)만 가지고 있으면 된다. 손님의 정보중에 로직에 필요한 부분은 사실 크지 않다. 단지 예약시 손님의 정보를 저장하는 것만 필요하다.
예약 클래스에는 손님 객체, 방 객체, 날짜 변수, uuid변수가 필요했다. 위에 말했듯, 호텔은 예약이 저장된 map에 value값으로 예약 객체를 갖고 있는다. 그 이유는 예약 객체에 예약 정보의 모든 것을 담아놨기때문. 따라서 예약 객체는 예약정보를 전부 담고 있어야 한다. 필요한 예약정보는 다음과 같다. [손님의 이름, 손님 전화번호, 예약 날짜, 방 호수] 이 모든것을 다뤄야 했기에 예약클래스에는 많은 필드값들을 가지게 되었다. 예약 클래스의 핵심 로직인 예약하기 방식은 다음과 같다.
첫번째조건) 손님의 소지금이 방의 가격보다 더 많다. 두번째조건) 해당 날짜에 방이 예약이 가능하다. 이다
첫번째 조건은 말그대로 저 조건으로 if문을 걸어준다. 두번째 조건에는 위에 설명한 방이 가지고 있는 date ArrayList에 해당하는 날짜가 있는지 확인하면 된다. (예약 성공시 방의 date ArrayList에 날짜가 추가됨) 방의 예약 가능 판단 메소드를 작동해서 T가 나오면 예약객체를 뱉어주면 된다! 이때 예약객체는 예약 한 고객, 방, 날짜 정보를 갖고 있는 객체를 반환한다.
또한 이때 UUID값을 SOUT을 통해 출력해준다. 그리고 예약이 성공시 호텔객체에 예약 정보를 담고있는MAP에 add를 해준다. 그리고 예약 확인과 삭제 메서드가 필요했다. 확인및 삭제 메소드는 호텔클래스에서 구현이 되면 된다(호텔이 예약 리스트를 갖음).
이런 방식으로 설계를 하는게 어떻냐고 팀원들에게 말했고 받아드려진 포인트가 있고 반려된 포인트가 있었다. 하지만 결국 대부분 받아드려져서 이런 흐름으로 프로젝트가 진행되고 있음!!
최종적으로 프로젝트가 끝나면 다시한번 정리하는 글을 써야겠다.