- 示例工程
【免费下载链接】awesome-low-level-design
Learn Low Level Design (LLD) and prepare for interviews using free resources.
本指南围绕开源仓库 awesome-low-level-design 中solutions/java/src/hotelmanagementsystem下的酒店管理系统(Hotel Management System)完整实现展开,从需求分析、核心实体建模到状态机、装饰器、观察者、规格模式与门面模式的落地应用,系统讲解如何在面试或项目中设计并实现一个可扩展的酒店预订系统。读完本文,你将掌握房间预订、入住/退房状态流转、增值服务计价、房间筛选与支付集成的完整 Java 实现方案,并能直接对照源码进行复现与二次扩展。
一、问题陈述与需求分析
根据 hotelmanagementsystem/README.md 的定义,本系统的核心目标是:设计并实现一个能够管理酒店房间、预订与客人信息的酒店管理系统,覆盖房间预订、入住、退房以及房间状态维护的完整业务闭环。
原始需求被划分为五个模块:
Room Management(房间管理)
- 跟踪不同类型房间(STANDARD、DELUXE、SUITE)
- 管理房间可用性与状态
- 处理房间定价与特性
Reservation Management(预订管理)
- 创建与管理预订
- 处理入住与退房流程
- 跟踪预订状态(CONFIRMED、CANCELLED、CHECKED_IN、CHECKED_OUT)
Guest Management(客人管理)
- 存储客人信息
- 跟踪客人历史
- 处理客人偏好
Room Status Tracking(房间状态跟踪)
- 监控房间可用性(AVAILABLE、OCCUPIED、MAINTENANCE)
- 基于预订更新房间状态
- 处理房间维护请求
Payment Integration(支付集成)
- 处理房间支付
- 支持不同支付方式
- 生成发票
二、核心实体建模(Core Entities)
README 给出了面向面试的简化实体设计,仓库中的实际实现在此基础上做了演进与增强。以下是两层的对应关系。
2.1 README 定义的简化实体
| 实体 | 关键字段 | 关键方法 |
|---|---|---|
HotelManagementSystem | List<Room>、List<Reservation>、List<Guest> | addRoom()、makeReservation()、checkIn()、checkOut()、getAvailableRooms()、cancelReservation() |
Room | roomNumber、type、price、status | isAvailable()、updateStatus()、getPrice() |
Guest | id、name、email、phoneNumber | updateProfile()、getReservations() |
Reservation | id、guest、room、checkInDate、checkOutDate、status | confirm()、cancel()、checkIn()、checkOut() |
RoomType(枚举) | STANDARD、DELUXE、SUITE | — |
RoomStatus(枚举) | AVAILABLE、OCCUPIED、MAINTENANCE | — |
ReservationStatus(枚举) | CONFIRMED、CANCELLED、CHECKED_IN、CHECKED_OUT | — |
2.2 仓库实际实现的核心实体
仓库实现保留了Room、Guest、Booking(对应 README 的Reservation)三个模型,但做了关键升级:
- Room.java:不再用简单的枚举字段表示状态,而是引入
RoomState state委托状态对象处理行为流转;同时用RoomStyle与RoomType两个维度刻画房间特性,例如 "DELUXE DOUBLE" 房间。 - Guest.java:保存
id、name、email,配合 UUID 风格的bookingId形成完整的客人—预订关联。 - Booking.java:持有
bookingId(由 BookingService.java 通过UUID.randomUUID()生成)、guest、room、startDate、endDate,创建时默认状态为BookingStatus.CONFIRMED,并提供checkIn()、checkOut()、cancel()方法流转状态。
对应枚举定义:
- RoomType.java:
SINGLE、DOUBLE、SUITE - RoomStyle.java:
STANDARD、DELUXE、OCEAN_VIEW - BookingStatus.java:
CONFIRMED、CHECKED_IN、CHECKED_OUT、CANCELLED
实现说明:README 中的
RoomType(STANDARD/DELUXE/SUITE)在实际代码中被拆分为RoomType(SINGLE/DOUBLE/SUITE)与RoomStyle(STANDARD/DELUXE/OCEAN_VIEW)两个独立维度,这让"类型 × 风格"的组合检索(如"预订一间 DELUXE 风格的 DOUBLE 房")在规格过滤时更精确。
三、系统整体架构与类图
3.1 架构分层
从源码结构看,该实现按职责划分为清晰的功能包:
solutions/java/src/hotelmanagementsystem/ ├── decorator/ # 增值服务装饰器(BreakfastDecorator、SpaDecorator、RoomBooking) ├── enums/ # RoomType、RoomStyle、BookingStatus ├── factory/ # RoomFactory 房间工厂 ├── model/ # Room、Guest、Booking 领域模型 ├── observer/ # BookingObserver、EmailNotifier、SmsNotifier ├── payment/ # Payment 接口、CashPayment、CreditCardPayment ├── specification/ # 规格模式:可用性/类型/风格组合筛选 ├── state/ # 房间状态机:AvailableState、OccupiedState、MaintenanceState ├── BookingService.java # 预订服务(含观察者通知) ├── RoomService.java # 房间仓储与查询 ├── PaymentService.java # 支付服务 ├── HotelManagerFacade.java # 门面:对外统一入口 └── HotelManagementDemo.java # 运行演示3.2 UML 类图
下图展示了该系统整体类结构与关系(对应仓库 class-diagrams/hotelmanagementsystem-class-diagram.png,即原 README 中引用的 UML 图的仓库实际位置):
四、关键设计模式实战剖析
README 的 "Design Patterns Used" 一节列出了 Singleton、Factory、Observer、Strategy,而仓库的实际实现更为丰富,共落地了6 个设计模式。下面逐一结合源码给出证据与调用链。
4.1 State 模式:房间状态机(最核心的实现)
README 要求跟踪AVAILABLE / OCCUPIED / MAINTENANCE三种房间状态,并"基于预订更新房间状态"。仓库用状态模式优雅地实现了这一点:
- 状态接口 RoomState.java 定义了四类事件:
book、checkIn、checkOut、markForMaintenance。 - 三个具体状态类各自定义"当前状态下允许的行为":
- AvailableState.java:可
book(转为OccupiedState)、可checkIn、可markForMaintenance(转为MaintenanceState);checkOut被拒绝。 - OccupiedState.java:仅允许
checkOut(回到AvailableState);book、checkIn、markForMaintenance均输出错误提示。 - MaintenanceState.java:禁止一切入住行为,再次调用
markForMaintenance视为维护完成、恢复为AvailableState。
- AvailableState.java:可
Room.java 初始化为AvailableState,并将book/checkIn/checkOut/markForMaintenance全部委托给当前状态对象(state.book(this))。这种设计的价值在于:状态流转规则被集中封装在状态类内部,Room 本身无需编写 if/else 判断,新增状态只需新增一个实现类。
4.2 Factory 模式:统一创建房间
RoomFactory.java 提供了静态工厂方法:
public static Room createRoom(String roomNumber, String type, String style, double price) { RoomType roomType = RoomType.valueOf(type.toUpperCase()); RoomStyle roomStyle = RoomStyle.valueOf(style.toUpperCase()); return new Room(roomNumber, roomType, roomStyle, price); }调用方只需传字符串(如"SINGLE"、"DELUXE"),工厂负责枚举解析与对象构造,将"创建细节"与"使用方"解耦。Demo 中用它批量初始化酒店房间(见 HotelManagementDemo.java)。
4.3 Decorator 模式:增值服务动态计价
README 提到"Handle room pricing and features"。仓库用装饰器模式实现"基础房价 + 增值服务"的动态组合:
- Bookable.java 定义
getCost()与getDescription()契约; - RoomBooking.java 是基础实现,返回房间原始价格;
BreakfastDecorator、SpaDecorator在保持Bookable接口不变的前提下,为描述追加服务名并叠加费用。
在 HotelManagerFacade.java 的bookRoom()中,装饰器按需嵌套:
Bookable bookable = new RoomBooking(room); for (String amenity : amenities) { if ("breakfast".equalsIgnoreCase(amenity)) { bookable = new BreakfastDecorator(bookable); } else if ("spa".equalsIgnoreCase(amenity)) { bookable = new SpaDecorator(bookable); } } System.out.println("Total Cost: " + bookable.getDescription() + " = $" + String.format("%.2f", bookable.getCost()));这种写法使得"含早餐"、"含 SPA"、"含早餐+SPA"等任意组合无需改动核心类即可扩展,符合开闭原则。
4.4 Observer 模式:预订通知
BookingService.java 内置观察者列表,支持addObserver/removeObserver,在createBooking()完成后调用notifyObservers(booking)逐个通知。
observer 包中提供了两个订阅者实现:EmailNotifier与SmsNotifier(均实现BookingObserver接口)。Demo 中通过bookingService.addObserver(new EmailNotifier())与addObserver(new SmsNotifier())完成注册——预订成功后即自动触发邮件与短信通知,为后续扩展"预订确认/提醒推送"提供了现成骨架。
4.5 Specification 模式:组合条件筛选房间
README 需求要求"Get available rooms"并按类型/风格检索。仓库用规格模式(Specification)替代传统的 if/else 查询:
- 基类 AbstractSpecification.java 提供
and()组合能力; - 三个具体规格:
RoomAvailableSpecification(可用性)、RoomTypeSpecification(类型)、RoomStyleSpecification(风格)。
RoomService.java 的findRooms(Specification<Room> spec)通过filter(spec::isSatisfiedBy)完成筛选,而 HotelManagerFacade.java 用链式组合一次性表达复杂查询:
Specification<Room> searchSpec = new RoomAvailableSpecification() .and(new RoomTypeSpecification(type)) .and(new RoomStyleSpecification(style)); Optional<Room> availableRoom = roomService.findRooms(searchSpec).stream().findFirst();4.6 Facade 模式 + Strategy 支付:统一门面与可插拔支付
HotelManagerFacade.java 作为对外门面,聚合RoomService、BookingService、PaymentService三个子系统,向调用方暴露bookRoom()、checkOut()等极简接口,隐藏了"查房 → 建预订 → 装饰计价 → 支付"的内部复杂调用链。
支付部分对应 README 的 Payment Integration 需求:payment包中定义了Payment接口,并有CashPayment与CreditCardPayment两个实现(Strategy 思想的体现),由 PaymentService.java 统一调用processPayment(amount),使"新增支付方式"只需新增一个实现类。
4.7 关于 Singleton 与 README 的差异说明
README 提到使用 Singleton 模式获取系统实例,但从当前源码结构看,服务对象(RoomService、BookingService、PaymentService、HotelManagerFacade)均由 HotelManagementDemo.java 通过new显式构造并注入,并未看到单例实现。这是 README 规划与仓库落地之间的差异,面试实现时可按需补充。
五、完整示例用法与运行演示
5.1 README 的简化示例
HotelManagementSystem system = new HotelManagementSystem(); // Add a room Room room = system.addRoom("101", RoomType.DELUXE, 150.0); // Create a guest Guest guest = new Guest("John Doe", "john@example.com", "1234567890"); // Make a reservation Reservation reservation = system.makeReservation(guest, room, checkInDate, checkOutDate); // Check in system.checkIn(reservation); // Check out system.checkOut(reservation);5.2 仓库的可运行 Demo(对应 README 的HotelManagementSystemDemo.java)
README 的 Demo 一节指向HotelManagementSystemDemo.java,即仓库中的 HotelManagementDemo.java。它演示了 5 个完整业务场景:
步骤 1:装配系统
RoomService roomService = new RoomService(); BookingService bookingService = new BookingService(); PaymentService paymentService = new PaymentService(); bookingService.addObserver(new EmailNotifier()); bookingService.addObserver(new SmsNotifier()); HotelManagerFacade hotelManager = new HotelManagerFacade(roomService, bookingService, paymentService);步骤 2:用工厂初始化 5 间房
roomService.addRoom(RoomFactory.createRoom("101", "SINGLE", "STANDARD", 100)); roomService.addRoom(RoomFactory.createRoom("102", "SINGLE", "DELUXE", 120)); roomService.addRoom(RoomFactory.createRoom("201", "DOUBLE", "STANDARD", 150)); roomService.addRoom(RoomFactory.createRoom("202", "DOUBLE", "DELUXE", 180)); roomService.addRoom(RoomFactory.createRoom("301", "SUITE", "OCEAN_VIEW", 300));场景 1:带增值服务的成功预订客人 G123(John Doe)通过hotelManager.bookRoom(guest, RoomType.DOUBLE, RoomStyle.DELUXE, now, now+3, List.of("Breakfast", "Spa"))预订 DELUXE 风格的双人房,附加早餐与 SPA,随后自动完成支付。
场景 2:并发预订被拒绝(State 模式验证)客人 G456(Jane Smith)用相同条件再次预订:由于 202 房已被 John Doe 占用,规格筛选找不到可用房间,输出 "Sorry, no rooms available matching your criteria.",这正是OccupiedState拒绝二次book的效果。
场景 3:退房后房间恢复可用(State 模式验证)hotelManager.checkOut("202")触发OccupiedState.checkOut(),房间状态打印由OccupiedState回到AvailableState,之后 G456 成功预订同一间房。
场景 4:维护状态拦截预订对 101 房调用markForMaintenance()后,其状态变为MaintenanceState;随后 G789 尝试预订 STANDARD 风格单人间,被维护状态拒绝,演示了维护期间房间不可售的规则。
5.3 运行方式
该模块为纯 Java 标准库实现(仅使用java.time.LocalDate、java.util.UUID等 JDK 类,无第三方依赖),可直接编译运行:
# 进入仓库根目录后 cd solutions/java/src javac hotelmanagementsystem/HotelManagementDemo.java java hotelmanagementsystem.HotelManagementDemo运行后将依次打印上述 5 个场景的预订结果、房间状态流转与总价输出。
六、异常处理设计
README 的 Exception Handling 一节规划了四类异常:
| 异常 | 触发场景 |
|---|---|
RoomNotAvailableException | 尝试预订不可用房间 |
InvalidReservationException | 预订详情非法 |
CheckInException | 入住流程失败 |
CheckOutException | 退房流程失败 |
从源码结构看,当前实现尚未定义独立的异常类,而是由状态模式在 state 包的各状态实现中以System.out.println("Error: ...")输出错误信息(如"Error: Room 202 is already occupied.")。这一设计选择体现了"状态合法性由状态机保证"的思路。若按 README 规划落地为受检异常,可让各状态类在非法操作时throw new RoomNotAvailableException(...),由 Facade 层统一捕获处理——这是面试时值得讨论的演进点。
七、框架扩展路线(Extending the Framework)
README 给出了六条清晰的扩展方向,结合现有架构可给出更具体的落地建议:
- Add room service(客房服务):可参考现有
PaymentService的服务类模式,新增RoomServiceRequest模型与工单状态机。 - Add housekeeping(保洁管理):保洁任务可复用
RoomState的MaintenanceState,再增加"待清洁/清洁中/已完成"子状态。 - Add loyalty program(会员积分):在
Guest上扩展积分字段,预订完成时通过现有 Observer 通知链触发积分累加。 - Add inventory management(库存管理):参考
RoomService.findRooms(spec)的规格模式,用Specification做库存条件查询。 - Add reporting system(报表系统):遍历
BookingService.bookings聚合入住率与营收,注意bookings目前为内存列表,生产环境应替换为持久化存储。 - Add notification system(通知系统):
BookingObserver已提供现成扩展点,新增PushNotifier实现接口并注册即可,无需改动业务代码。
八、小结:面试回答的完整叙事线
综合 README 与源码,这套酒店管理系统可总结为一条清晰的面试叙事线:
- 需求层:五大模块(房间、预订、客人、状态、支付)被完整覆盖;
- 实体层:
Room/Guest/Booking三模型 + 三枚举,RoomType × RoomStyle双维度刻画房型; - 行为层:
State状态机管理房间生命周期,Specification组合筛选,Decorator动态计价,Observer事件通知,Factory统一构造,Facade封装门面,Payment策略化支付; - 演示层:HotelManagementDemo.java 用 5 个场景覆盖成功预订、冲突拒绝、退房释放、维护拦截的完整流转。
仓库中该模块位于 solutions/java/src/hotelmanagementsystem,类图见 class-diagrams/hotelmanagementsystem-class-diagram.png,其余 30+ 个低层设计题目(停车系统、电梯、LRU Cache、棋类游戏等)可在仓库 problems 与 solutions 目录中继续探索。
- 示例工程
【免费下载链接】awesome-low-level-design
Learn Low Level Design (LLD) and prepare for interviews using free resources.
相关推荐
酒店管理系统(Hotel Management System)低层设计实战:基于 awesome-low-level-design 的 C++ 全流程实现解析
酒店管理系统(Hotel Management System)低层设计实战:基于 awesome low level design 的 C++ 全流程实现解析
示例工程在线拍卖系统低层设计(LLD)实战:基于 awesome-low-level-design 的 C++ 实现全解析
在线拍卖系统低层设计(LLD)实战:基于 awesome low level design 的 C++ 实现全解析 本篇技术指南以 awesome low le
示例工程汽车租赁系统低层设计(LLD)实战指南:基于 awesome-low-level-design 的需求建模与并发实现
汽车租赁系统低层设计(LLD)实战指南:基于 awesome low level design 的需求建模与并发实现 导读 本指南以 problems/car
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考