Design problems: Reservation system

EDIT -- on second thought, why not just let each Room have a list of Reservation instances, which in turn have start/end properties that tell you when the reservation occurs?

That way, to tell if a room has a reservation for a certain time, you just loop thru the reservations for the room and see if the time in question is within the start/end range of any of the reservations...granted that code is not too easy (nor too hard) to implement, but that's the basic idea.


Think about it, Room is a resource that you can reserve for a given time range. Also you have several rooms which can be reserved independently. How would you implement the following methods:

class Room {
  boolean isAvailable(Date date) {/*...*/}
  Date nextAvailableDate() {/*...*/}
}

Hint: room has to know about its reservations.

It's not clear from your question what is the purpose of Reservation. Does it only contain a date range or is it assigned to a particular room? If the former, you might encounter a problem of finding a free room for a new reservations - this can be easily implemented by looping over all rooms and using methods above.

If the latter: since the reservations knows about the room, the room may also know about the reservation. So implementing the methods above is trivial by iterating over reservations.


Create three classes (Hotel, Room & Reservation) :

  • Reservation object is used like an invoice here, and is kept decoupled from booking process.

  • Each Room object (dedicated for each room number in the hotel) contains a map which stores reservedDates as key and reservationObject as value.

  • Hotel composes of rooms. For each booking request, Hotel loops through the room list, and with that, each room traverse through its own map to find if the booking is possible for asked days.

Note that the booking function is taking dates as list, not just two dates (as startDate and endDate). It's same thing as the former can be derived from the later.

Sample Code is as below:

class Hotel {
    private String name, address;
    private List<Room> roomList;   //key : roomNumber
    public Hotel(){
        roomList = new ArrayList<Room>();
    }
    public Reservation bookRoomForDates(List<Integer> dateList, Guest guest){
        for(Room room : roomList){
            Reservation reservation = room.bookForGivenDates(dateList, guest);
            if(reserved != null) return reservation; //Reservation successFull!
        }
        return null; //Reservation failed!
    }
}
class Reservation {
    private String id;
    private Date inDate, outDate;
    private Guest guest;

    public Reservation(Room room, int startDate, int endDate, Guest guest){
        //populate the member variables.
    }
}

class Room {
    private String id;
    private int roomNumber, floorNum;
    private Map<Integer, Reservation> reservedDates;  // key : date as Integer (YYYYMMDD)

    public Room(int roomNumber){
        reservedDates = new HashMap<Integer, Reservation>();
        this.roomNumber = roomNumber;
    }

    //A guest request for booking on dates(in YYYYMMDD format) in the dateList
    public Reservation bookForGivenDates(List<Integer> dateList, Guest guest)  
    {   
        if(dateList.isEmpty()) return null;

        for(Integer date : dateList){
            Reservation res = reservedDates.get(date);  
            if(res != null) {  // We don't store null value for unreserved dates for the room.
                return null;  // Room is reserved on this date by another guest. So, this room is unavailable.
            }
        }
        //this room is unreserved on all requested dates. So go on and reserve this room for asked dates
        int startDate = dateList.get(0);
        int endDate   = dateList.get(dateList.size() - 1);

        Reservation newReservation = new Reservation(this, startDate, endDate, guest);
        for(Integer date : dateList){
            reservedDates.put(date, newReservation);
        }
        return newReservation;
    }
}

Tags:

Java