OO-Unit4-UML与图书管理系统 暨OO课程总结
UML正向建模与开发
第四单元的核心目标是实践先建模、后编码的正向开发流程。三次作业均要求先绘制UML类图,再依据模型实现代码,最后进行模型与代码的一致性检查。
本单元采用了两阶类图的建模策略:
- 初始类图:在通读需求后绘制,用于梳理核心领域对象(如
Library、User、Book及各Office)及其静态关系,确定模块边界与职责划分。初始类图帮助我们建立对业务域的整体认知,避免一开始就陷入实现细节。 - 详细类图:在初始类图的基础上,补充属性类型、方法签名、关联多重性、依赖方向等细节,作为编码阶段的直接蓝图。详细类图迫使我们在动手写代码前思考状态封装、信息隐藏与协作协议。
两阶类图的作用在于渐进式精化:初始类图回答"有哪些对象、对象之间是什么关系",详细类图回答"对象如何协作、状态如何流转"。这种分层降低了单次认知负荷,也让UML成为贯穿开发周期的活文档。在图书管理系统的三次迭代中,借助初始类图快速定位新增需求对现有架构的改变,再在详细类图中细化新增的GradeManager、CreditManager与既有模块的依赖关系,从而实现了平滑的增量演进。
架构设计
本单元三次作业的架构遵循“Library门面 + 区域管理器 + 值对象”的分层思路:
Library作为统一门面,承担开闭馆时的书籍流转编排;CommandHandler负责请求路由与校验逻辑;BookshelfManager、AppointmentOffice、BorrowAndReturnOffice、ReadingRoom、OrderManager、GradeManager、CreditManager等各司其职,封装对应业务规则;Book、User、BorrowRecord等作为领域对象,维护自身状态。
代码与UML模型的追踪关系:代码结构基本忠实于UML设计。类图中定义的每一个实体类都在代码中有直接对应;关联关系通过组合成员变量实现;状态转移则映射为Book的状态字段与Library.morningSort()/eveningSort()中的编排逻辑。此外,部分查询与遍历逻辑在代码中做了性能导向的微调(如HashMap索引、HashSet去重),这些是UML静态视图难以体现的工程权衡。
大模型辅助正向建模体验
在第四单元中尝试使用大模型辅助UML建模,核心体会是:大模型擅长局部细节补全,但难以自主完成跨模块的架构决策。为引导模型在复杂场景中完成架构设计任务,我总结出以下经验:
- 先给框架,再填细节:先向模型提供需求摘要与初始类图骨架,限定领域对象集合,再让模型补充各类的属性与方法。
- 分场景定义行为契约:对开闭馆时的书籍流转、预约过期判定等复杂行为,用自然语言伪代码或状态机描述预期流程,再让模型生成对应的类协作图或顺序草图。
- 迭代纠偏,而非一次性生成:模型容易在关联方向、多重性或职责分配上出现偏差。通过多轮"指出问题→给出原则→重新生成"的反馈循环,逐步收敛到符合高内聚低耦合目标的模型。
- 以代码可追踪性为检验标准:最终让模型根据类图生成Java骨架代码,通过编译与单元测试反向验证模型的一致性。这种"模型→代码→测试"的闭环是检验正向建模质量的硬指标。
架构设计思维
四个单元的架构思维演进可以概括为一条从微观过程书写到宏观架构设计的曲线:
- Unit1(表达式解析):架构核心围绕算法与数据结构展开。关注点在于如何用递归下降法将线性输入转化为树形/多项式结构,
Lexer、Parser、Poly的拆分本质上是编译前端的标准流水线,对象在此处更多是"数据容器"而非"行为主体"。 - Unit2(电梯调度):架构核心转向交互与并发。需要开始考虑线程安全、共享状态与协作式调度,
ElevatorTable作为共享状态中心,Solver作为决策引擎,Dispatcher作为负载均衡器——架构设计开始关注运行时的行为交互与并发,而不仅仅是静态数据结构。 - Unit3(JML社交网络):架构核心进入契约化设计。JML规格强迫我们"先约定后实现",
Network、User、Video之间的协作完全由前置条件、后置条件与不变式约束。这一单元让我体会到接口即契约:架构的稳定性来自于对外暴露行为的精确规约,而非内部实现的精巧。 - Unit4(UML图书管理):架构核心落脚于领域建模与正向设计。对象不再只是实现工具,而是对业务概念的映射(
Book、User、AppointmentOffice)。架构设计从"怎么写代码"前置到"怎么理解需求、怎么划分类、怎么分配职责"。
总体而言,演进脉络是从以算法为中心到以对象协作为中心,再到以模型契约为中心,最终走向以领域理解为中心的正向设计。
测试思维
四个单元的测试策略同样经历了显著升级:
- Unit1:以手造边界数据为主。针对括号嵌套、大整数、零次幂、函数递归等构造极端表达式,测试重点是计算正确性与边界鲁棒性。
- Unit2:引入自动化评测与并发压力测试。电梯单元的bug大量出现在时序与线程安全上,手造数据难以覆盖,因此依赖随机数据生成器进行高并发压力测试,同时借助输出序列的合法性检查(如不能关门后再开门、不能超载)进行自动化判定。
- Unit3:转向规格驱动的测试。依据JML的
requires、ensures、signals逐条构造满足/不满足前置条件的用例,确保每条异常路径都被触发。同时利用JUnit对查询类方法进行等价类划分与重点方法验证。 - Unit4:结合状态机测试与场景驱动测试。图书管理系统的状态流转复杂(预约、过期、取书、归还、续借、信用扣减),测试用例围绕"状态边"设计:针对每一条可能的状态转移构造开闭馆序列与用户请求序列,验证书籍轨迹(
LibraryMoveInfo)与对象状态的一致性。
测试思维的核心演进是从验证结果正确到验证行为合规,再到验证契约履行。好的测试不是证明代码正确性,而是尽可能暴露设计与实现之间的偏差。
课程收获
一学期的OO课程下来,最大的收获不是学会了某几种设计模式或多线程技巧,而是建立了以模型驾驭复杂度的工程意识。四个单元从解析表达式到调度电梯,再到社交网络与图书管理,问题域不断扩展,但应对复杂度的手段也从"写更巧妙的代码"转变为"画更清晰的图、定更明确的契约、分更合理的模块"。
更重要的是,我体会到了架构设计是一个持续决策的过程:没有完美的初始设计,只有在需求演进中不断评估、调整与折中。面向对象不仅是封装、继承、多态三条语法规则,更是一种将现实世界概念映射为软件结构的思维方式。这种思维,将比任何具体的代码技巧更长久地影响工程实践。
