☰
航空管理系统 LLD 实战:基于 awesome-low-level-design 的 Java 领域建模与完整实现解析
2026/10/2 8:11:45 网站建设 项目流程
  • 示例工程

【免费下载链接】awesome-low-level-design

Learn Low Level Design (LLD) and prepare for interviews using free resources.

项目地址:https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design
点击查看免费下载

本篇文章以 solutions/java/src/airlinemanagementsystem/README.md 为骨架,结合仓库内完整的 Java 源码,系统讲解航空管理系统(Airline Management System)的低层设计(LLD)思路:从问题陈述、需求分析到核心实体识别、类设计、UML 建模,再到可运行的示例代码与扩展方向。读者学完后,将能够独立搭建一个涵盖航班、飞机、座位、乘客、预订与支付六大模块的航空业务系统,并理解其背后单例、状态机等设计模式的落地方式。

问题陈述与需求分析

问题陈述

Design and implement an Airline Management System that allows users to book flights, manage passengers, handle seat assignments, process payments, and track bookings and flights.

即:设计并实现一个航空管理系统,支持用户预订航班、管理乘客、处理座位分配、处理支付,并跟踪预订与航班状态。这是面试中经典的领域建模题目,考察的是对真实业务实体、实体关系与业务状态流转的抽象能力。

需求要点

原文档明确列出了七条核心需求,它们是整个类设计的输入:

需求说明
航班管理每个航班拥有唯一航班号、关联飞机、出发地、目的地与时刻表
飞机管理每架飞机有型号(model)与一组座位(seats)
座位管理系统为每个航班管理座位分配与可用性
乘客管理乘客可被新增、更新,并与预订关联
预订管理用户可预订航班,系统跟踪预订、已分配座位与乘客
支付处理系统为预订处理支付
可扩展性易于扩展忠诚度计划、餐食选择、多航段旅程等新特性

面向对象设计原则的体现

从源码结构看,本实现遵循了几个典型的 LLD 原则:

  • 单一职责:Flight只关注航班本身,Seat只负责座位状态,BookingManager独立管理预订生命周期;
  • 封装:座位状态、预订状态均通过方法(reserve()/release()/cancel())改变,外部不能直接改写;
  • 领域包划分:源码按业务域组织为flight/、seat/、booking/、payment/四个子包,外加根包下的Aircraft、Passenger、AirlineManagementSystem,职责边界清晰。

核心实体设计

原文档给出了七大核心实体,它们在仓库源码中均有对应类:

实体所在路径职责
AirlineManagementSystemAirlineManagementSystem.java门面入口,统一管理航班、乘客、预订与支付
Flightflight/Flight.java航班,含航班号、飞机、起降地、时刻与座位
AircraftAircraft.java飞机,含尾号、型号与总座位数
Seatseat/Seat.java座位,含座位号、舱位类型与可用状态
PassengerPassenger.java乘客,含 ID、姓名与邮箱
Bookingbooking/Booking.java预订,关联乘客、航班、座位与价格
Paymentpayment/Payment.java支付交易,含支付 ID、方式、金额与状态

实体关系

从源码可以确认实体之间的聚合与关联关系:

  • Flight聚合Aircraft,并持有Map<String, Seat>座位表与List<Seat> availableSeats可用座位缓存;
  • Aircraft在构造时按totalSeats建立座位集合(见 Aircraft.java 构造逻辑);
  • Booking关联一个Flight、一个Passenger、一个Seat;
  • Payment独立于Booking,由PaymentProcessor统一处理。

类设计详解

1. AirlineManagementSystem(门面类)

原文档描述的字段为List<Flight> flights, List<Booking> bookings, List<Passenger> passengers, PaymentProcessor paymentProcessor。仓库实现进一步演进为以 Map 为主、以服务类为辅的架构:

private final Map<String, Flight> flights; private final Map<String, Aircraft> aircrafts; private final Map<String, Passenger> passengers; private final FlightSearch flightSearch; private final BookingManager bookingManager; private final PaymentProcessor paymentProcessor;

关键方法(与 AirlineManagementSystem.java 对应):

方法作用
addPassenger(name, email)创建乘客并登记,返回乘客对象
addAircraft(tailNumber, model, totalSeats)以尾号登记飞机
addFlight(source, destination, departure, arrival, aircraftNumber)创建航班并加入搜索索引
searchFlights(source, destination, date)委托FlightSearch按条件检索
bookFlight(flightNumber, passengerId, seat, price)委托BookingManager创建预订
cancelBooking(bookingNumber)委托BookingManager取消预订
processPayment(payment)委托PaymentProcessor处理支付

值得注意的是:bookFlight返回类型为Booking(可空),调用方需判空;而原文档示例中的bookFlight(Passenger, Flight, Seat, Payment)签名在仓库中演化为按 ID 引用,这样更贴近真实系统的解耦风格。

2. Flight(航班)

源码中Flight的字段为:

private final String flightNumber; // UUID 生成,保证唯一 private final String source; private final String destination; private final LocalDateTime departureTime; private final LocalDateTime arrivalTime; private final FlightStatus status; // ON_TIME / DELAYED / CANCELLED private final Aircraft aircraft; private final Map<String, Seat> seats; private final List<Seat> availableSeats;

与文档字段(String flightNumber, Aircraft aircraft, String source, String destination, Date schedule, List<Seat> seats)相比,仓库实现将时间细化为了departureTime与arrivalTime两个LocalDateTime,并新增了FlightStatus状态机,便于后续支持延误、取消等真实场景。

座位管理的关键是并发安全:isSeatAvailable、reserveSeat、releaseSeat全部以synchronized修饰(见 flight/Flight.java),防止同一座位被并发重复预订。

3. Aircraft(飞机)

private final String tailNumber; // 机尾编号,作为唯一标识 private final String model; // 如 Boeing 747、Airbus A380 private final int totalSeats; // 总座位数

注意:文档中Aircraft描述为"model + seats",仓库实现则以tailNumber作为注册键,totalSeats决定座位数量,见 Aircraft.java。

4. Seat(座位)

private final String seatNumber; private final SeatType type; // ECONOMY / PREMIUM_ECONOMY / BUSINESS / FIRST_CLASS private SeatStatus status; // AVAILABLE / RESERVED / OCCUPIED(见 SeatStatus)
  • reserve()将状态置为RESERVED;
  • release()将状态置回AVAILABLE;
  • isBooked()用synchronized保证读安全,判断是否为OCCUPIED(见 seat/Seat.java)。

5. Passenger(乘客)

字段为id(UUID)、name、email。与文档的int id, String name, String contactInfo相比,仓库实现将 ID 改为 UUID 字符串,联系方式收敛为email,更贴合现代系统。

6. Booking(预订)

private final String id; private final Flight flight; private final Passenger passenger; private final Seat seat; private final double price; private BookingStatus status; // CONFIRMED / CANCELLED / PENDING / EXPIRED

cancel()方法在将状态置为CANCELLED的同时调用seat.release()释放座位(见 booking/Booking.java),体现了座位资源与预订状态的一致性维护——这是预订系统的关键设计点。

7. Payment 与 PaymentProcessor(支付)

public class Payment { private final String paymentId; private final String paymentMethod; // 如 CREDIT_CARD private final double amount; private PaymentStatus status; // PENDING / COMPLETED ... }

Payment.processPayment()完成支付逻辑并将状态置为COMPLETED(见 payment/Payment.java);PaymentProcessor以单例模式封装处理入口(见 payment/PaymentProcessor.java)。

8. BookingManager 与 PaymentProcessor:单例模式落地

仓库中BookingManager与PaymentProcessor均采用双重用途的单例模式——getInstance()方法加synchronized,私有构造函数确保全局唯一:

public static synchronized BookingManager getInstance() { if (instance == null) { instance = new BookingManager(); } return instance; }

预订创建与取消操作在synchronized(lock)块内执行(见 booking/BookingManager.java),避免并发下 Map 数据竞争。

UML 类图

仓库根目录提供了与本主题强相关的类图:

该图直观展示了AirlineManagementSystem与Flight、Aircraft、Passenger、Booking、Payment等实体之间的聚合与关联关系,可作为面试讲解时的辅助图示。

示例用法与 Demo

原文档示例代码

原文档给出了最简演示流程:

AirlineManagementSystem system = new AirlineManagementSystem(); Aircraft aircraft = new Aircraft("Boeing 737", seatList); Flight flight = new Flight("AI101", aircraft, "DEL", "BOM", new Date(), seatList); system.addFlight(flight); Passenger alice = new Passenger(1, "Alice", "alice@email.com"); system.addPassenger(alice); Seat seat = flight.getAvailableSeats().get(0); Payment payment = new Payment(1, 5000.0, "CREDIT_CARD"); system.bookFlight(alice, flight, seat, payment);

仓库真实 Demo 流程

仓库中的 AirlineManagementSystemDemo.java 展示了更贴近实际 API 的完整调用链,对应五个步骤:

  1. 创建乘客:addPassenger("John Doe", "john@example.com");
  2. 注册飞机:addAircraft("A001", "Boeing 747", 300)(300 座);
  3. 创建航班:addFlight("New York", "London", departureTime, arrivalTime, "A001"),时刻用LocalDateTime.now().plusDays(1)模拟次日起飞;
  4. 搜索航班:searchFlights("New York", "London", LocalDate.now().plusDays(1));
  5. 预订与取消:bookFlight(flight1.getFlightNumber(), passenger1.getId(), new Seat("25A", SeatType.ECONOMY), 100),随后cancelBooking(booking.getId())释放座位。

其中FlightSearch.searchFlights使用流式过滤完成三条件匹配(出发地、目的地、日期,见 flight/FlightSearch.java),是理解搜索链路的关键实现。

可运行性说明

本实现基于 Java 8+(使用java.timeAPI),无第三方依赖,可直接编译运行:进入 solutions/java/src 目录,将airlinemanagementsystem包加入 classpath 后执行AirlineManagementSystemDemo即可看到搜索、预订、取消的完整输出。这是仓库所有 LLD 题目的统一 Java 组织方式,便于面试前快速演示。

扩展方向:框架的可扩展性

原文档最后给出了三个扩展方向,结合源码可给出具体落点:

  • 忠诚度计划(Loyalty Program):可在Passenger上增加积分字段,或在Payment完成后增加积分回写钩子,不侵入现有Booking核心链路;
  • 餐食选择(Meal Selection):为Booking增加可选的mealPreference属性,或在BookingManager.createBooking中增加可选参数重载;
  • 多航段旅程(Multi-leg Journey):将Booking与Flight的一对一关系演进为Booking持有List<Flight>,同时让Flight支持中转衔接字段。

从源码结构看,AirlineManagementSystem已把所有业务委托给FlightSearch、BookingManager、PaymentProcessor三个独立服务,新增上述功能只需替换或扩展对应服务,无需改动门面调用方——这正是本设计预留的扩展点。

小结

通过本文可以掌握一条完整的 LLD 落地链路:需求分析 → 实体识别 → 类设计 → 状态建模 → 门面服务分层 → 并发安全 → 可运行 Demo → 扩展预留。仓库中该题的完整源码位于 solutions/java/src/airlinemanagementsystem,配合 class-diagrams/airlinemanagementsystem-class-diagram.png 类图,可作为面试复习的高质量参照;同一仓库还提供了 C++、C#、Go 等语言的对应实现,便于横向对比各语言的领域建模风格。

  • 示例工程

【免费下载链接】awesome-low-level-design

Learn Low Level Design (LLD) and prepare for interviews using free resources.

项目地址:https://gitcode.com/GitHub_Trending/aw/awesome-low-level-design
点击查看免费下载
上一篇:如何快速配置vJoy虚拟手柄:5个步骤让键盘变专业游戏控制器
下一篇:5分钟掌握DLSS Swapper:开源游戏性能优化终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询