Determine the different ways the system will be used. This includes main functions the system needs to perform and who will use it.
1) Users should be able to register and log ing
2) User can view their profiles and booking histories
3)The system should allow hotel admins to add, update, or remove rooms.
4) Each room should have attributes like type (single, double, suite), price, and availability status
5) Users can search for available rooms by date, room type, and location.
6) Users should be able to filter search results based on price range, room type, and amenities
7) Users should be able to book a room, specifying the check-in and check-out dates.
8) The system should validate room availability before confirming a booking.
9) Users should be able to make payments for their bookings through secure payment methods (credit card, debit card, etc.).
+
Based on the requirements and use cases, identify the main objects of the system...
1) Account
2) User
3) Admin
4)Rooms
5) Search
6) Search By Check In Date
7) Search By Check out Date
8) Hotel Type -> Enumeration for differnt types fo hotel
9) Hotel -> Centreal type for all the hotels
10 Booking Manager -> For doing the booking
11 ) For doing the booking
12) Payment
13 Payment by card
14) payment by cheque
Determine how these objects will interact with each other to fulfill the use cases...
1) Each User and Admin class will extend the account class
2) Each admin class will have an instance of hotel class through which they can add rooms
3)Each hotel will hold the list of rooms
4) Admin will communicate with room manager for adding and deleting the rooms
5) Each User will have instance of booking manager using which they can book the room
6)Search class will be an interface which will be extended by different subclasses like search by checkInDate, checkoutDate and etc
7)Payment will be an interface and payByDebitCard,PayByCreditCard will extend these interfaces
Design inheritance trees where applicable to promote code reuse and polymorphism. This step involves identifying common attributes and behaviors that can be abstracted into parent classes...
1) Each User and Admin class will extend the account class
2) Each admin class will have an instance of hotel class through which they can add rooms
3)Each hotel will hold the list of rooms
4) Admin will communicate with room manager for adding and deleting the rooms
5) Each User will have instance of booking manager using which they can book the room
6)Search class will be an interface which will be extended by different subclasses like search by checkInDate, checkoutDate and etc
7)Payment will be an interface and payByDebitCard,PayByCreditCard will extend these interfaces
Consider using design patterns (e.g., Factory, Singleton, Observer, Strategy) that fit the problem...
We will be using strategy patter for different payment strategies like pay by card, pay by credit card, pay by check etc
we will be using factory method for search functionality like search by check-in date, search by checkout -out date etc.
Finally we will be using decorator design pattern to add different aminities to the room.
Attributes: For each class, define the attributes (data) it will hold...
Methods: Define the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation.
package model;
import java.util.*;
// Base Account class
abstract class Account {
protected String username;
protected String password;
protected String email;
public Account(String username, String password, String email) {
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return username;
}
}
// User class extending Account
class User extends Account {
private BookingManager bookingManager;
public User(String username, String password, String email, BookingManager bookingManager) {
super(username, password, email);
this.bookingManager = bookingManager;
}
public void bookRoom(Hotel hotel, Room room) {
bookingManager.bookRoom(hotel, room, this);
}
}
// Admin class extending Account
class Admin extends Account {
private Hotel hotel;
private RoomManager roomManager;
public Admin(String username, String password, String email, Hotel hotel, RoomManager roomManager) {
super(username, password, email);
this.hotel = hotel;
this.roomManager = roomManager;
}
public void addRoom(Room room) {
roomManager.addRoom(hotel, room);
}
public void deleteRoom(Room room) {
roomManager.deleteRoom(hotel, room);
}
}
// Room interface
interface Room {
String getRoomNumber();
double getPrice();
String getDescription();
}
// Concrete Room class
class BasicRoom implements Room {
private String roomNumber;
private double price;
public BasicRoom(String roomNumber, double price) {
this.roomNumber = roomNumber;
this.price = price;
}
@Override
public String getRoomNumber() {
return roomNumber;
}
@Override
public double getPrice() {
return price;
}
@Override
public String getDescription() {
return "Basic Room";
}
}
// Decorator for Room
abstract class RoomDecorator implements Room {
protected Room decoratedRoom;
public RoomDecorator(Room room) {
this.decoratedRoom = room;
}
@Override
public String getRoomNumber() {
return decoratedRoom.getRoomNumber();
}
@Override
public double getPrice() {
return decoratedRoom.getPrice();
}
@Override
public String getDescription() {
return decoratedRoom.getDescription();
}
}
// Concrete Decorator for adding WiFi
class WiFiDecorator extends RoomDecorator {
public WiFiDecorator(Room room) {
super(room);
}
@Override
public double getPrice() {
return decoratedRoom.getPrice() + 10; // Adding WiFi increases price by 10
}
@Override
public String getDescription() {
return decoratedRoom.getDescription() + ", WiFi";
}
}
// Concrete Decorator for adding Breakfast
class BreakfastDecorator extends RoomDecorator {
public BreakfastDecorator(Room room) {
super(room);
}
@Override
public double getPrice() {
return decoratedRoom.getPrice() + 20; // Adding breakfast increases price by 20
}
@Override
public String getDescription() {
return decoratedRoom.getDescription() + ", Breakfast";
}
}
// Concrete Decorator for adding Sea View
class SeaViewDecorator extends RoomDecorator {
public SeaViewDecorator(Room room) {
super(room);
}
@Override
public double getPrice() {
return decoratedRoom.getPrice() + 30; // Adding sea view increases price by 30
}
@Override
public String getDescription() {
return decoratedRoom.getDescription() + ", Sea View";
}
}
// Hotel class holding list of rooms
class Hotel {
private String hotelName;
private List<Room> rooms;
public Hotel(String hotelName) {
this.hotelName = hotelName;
this.rooms = new ArrayList<>();
}
public void addRoom(Room room) {
rooms.add(room);
}
public void deleteRoom(Room room) {
rooms.remove(room);
}
public List<Room> getRooms() {
return rooms;
}
}
// RoomManager responsible for adding and deleting rooms
class RoomManager {
public void addRoom(Hotel hotel, Room room) {
hotel.addRoom(room);
System.out.println("Room added: " + room.getRoomNumber() + " in " + hotel.getRooms().size());
}
public void deleteRoom(Hotel hotel, Room room) {
hotel.deleteRoom(room);
System.out.println("Room removed: " + room.getRoomNumber());
}
}
// BookingManager responsible for booking rooms
class BookingManager {
public void bookRoom(Hotel hotel, Room room, User user) {
if (hotel.getRooms().contains(room)) {
System.out.println(user.getUsername() + " has booked " + room.getDescription() + " (Room " + room.getRoomNumber() + ") at " + room.getPrice());
} else {
System.out.println("Room not available.");
}
}
}
// Search interface
interface Search {
List<Room> search(Hotel hotel);
}
// Search by Check-In Date
class SearchByCheckInDate implements Search {
private String checkInDate;
public SearchByCheckInDate(String checkInDate) {
this.checkInDate = checkInDate;
}
@Override
public List<Room> search(Hotel hotel) {
// Dummy implementation
return hotel.getRooms(); // Assume all rooms are available on checkInDate
}
}
// Search by Check-Out Date
class SearchByCheckOutDate implements Search {
private String checkOutDate;
public SearchByCheckOutDate(String checkOutDate) {
this.checkOutDate = checkOutDate;
}
@Override
public List<Room> search(Hotel hotel) {
// Dummy implementation
return hotel.getRooms(); // Assume all rooms are available on checkOutDate
}
}
// Payment interface
interface Payment {
void pay(double amount);
}
// Pay by Debit Card
class PayByDebitCard implements Payment {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " using Debit Card.");
}
}
// Pay by Credit Card
class PayByCreditCard implements Payment {
@Override
public void pay(double amount) {
System.out.println("Paid " + amount + " using Credit Card.");
}
}
// Main class to demonstrate usage
class HotelManagementSystem {
public static void main(String[] args) {
// Create Hotel
Hotel hotel = new Hotel("Grand Plaza");
// Create RoomManager and Rooms
RoomManager roomManager = new RoomManager();
Room basicRoom1 = new BasicRoom("101", 100);
Room basicRoom2 = new BasicRoom("102", 150);
// Decorate rooms
Room wifiRoom = new WiFiDecorator(basicRoom1);
Room breakfastRoom = new BreakfastDecorator(wifiRoom); // WiFi + Breakfast
Room seaViewRoom = new SeaViewDecorator(basicRoom2); // Sea View
// Add decorated rooms to hotel
roomManager.addRoom(hotel, breakfastRoom);
roomManager.addRoom(hotel, seaViewRoom);
// Create BookingManager and User
BookingManager bookingManager = new BookingManager();
User user = new User("user1", "user123", "user@hotel.com", bookingManager);
// User books a room
user.bookRoom(hotel, breakfastRoom);
// Search rooms by Check-In Date
Search searchByCheckInDate = new SearchByCheckInDate("2024-09-15");
List<Room> availableRooms = searchByCheckInDate.search(hotel);
System.out.println("Available rooms: " + availableRooms.size());
// Payment via Credit Card
Payment payment = new PayByCreditCard();
payment.pay(breakfastRoom.getPrice());
}
}
Check and explain whether your design adheres to solid principles (Ask interviewer what SOLID principle is if you can not recall it.)...
The hotel management system follows SOLID principles by ensuring each class has a single responsibility (SRP), allowing new functionality like search filters and payment methods to be added without modifying existing code (OCP), enabling interchangeable use of subclasses like PayByCreditCard via interfaces (LSP), defining focused interfaces for search and payment (ISP), and depending on abstractions (Room, Payment) rather than concrete implementations (DIP).
Explain how your design can handle changes in scale and whether it would be easily to extend with new functionalities...
In the solution we have heavily used interfaces and abstractions which can be easliy extended and offers high scalability and flexibility
Try creating a class, flow, state and/or sequence diagram using the diagramming tool. Mermaid flow diagrams can be used to represent system use cases. You can ask the interviewer bot to create a starter diagram if unfamiliar with the tool. Briefly explain your diagrams if necessary...
Created class diagram for the above solution
Critically examine your design for any flaws or areas for future improvement...