272
社区成员




本单元的任务总结为:
在本单元中,我深刻体会到了正向建模流程的价值:
先设计,后编码
通过分析图书馆业务场景,将借阅、预约、取书、阅读、归还、查询整理等核心需求抽象为 UML 类图、状态图、顺序图,明确各实体与服务的职责边界。
在动手写 Java 代码前,先把「Book」「Copy」「User」「Office」等类、它们的属性与方法、类之间的关联、状态机的触发条件、消息交互时序都图形化表现出来,使得后续实现有了清晰的蓝图。
增量迭代
随着作业从第 13 次到第 15 次,业务不断演进:先实现借阅、预约、取书,再扩展热门书架,再加入阅读、归还,最后引入借阅期限与信用分。每次都先在 UML 中更新设计,再在代码中增量实现。
这种“设计→图 → 代码 → 测试 → 再设计”的闭环,让我对大规模系统的架构演进有了更直观的认识。
MainClass:从官方包读取初始库存 ,然后用一个无限循环来处理每条命令
Library
作为核心协调者,内部持有对各“办公室”或“房间”模块的引用:Bookshelf
(普通书架)、AppointmentOffice
(预约处)、BorrowReturnOffice
(借还处)、ReadingRoom
(阅览室)
存储所有用户 (User
对象) 以及所有预约记录 (Reservation
对象)。
实现了所有业务命令对应的 handleBorrow
、handleReturn
、handleAppointment
、handlePick
、handleRead
、handleRestore
、handleQueryTrace
、handleQueryCredit
、handleOpen
、handleClose
等方法。
Bookshelf / AppointmentOffice / BorrowReturnOffice / ReadingRoom:每个类负责管理自己“位置”上的图书副本集合,并能提供增删接口
User:保存用户的 creditScore
、当前持有的图书副本、当日阅读/预约状态,并封装了信用分和资格检查逻辑。
Reservation:记录一条“谁预约了哪个 ISBN、何时预约、何时送达、保留至何时”
UML类图如下:
开/闭馆整理 (handleOpen
/ handleClose
)
开馆后整理:
把副本搬回书架或热门书架;
将过期的 Reservation
从 AppointmentOffice
回收;
更新“热门书架”标记(根据上次闭馆以来被借阅/阅读的 ISBN 列表),并把在架书籍移动到对应的 Bookshelf
或 HotBookshelf
。
闭馆后整理:
将仍在 ReadingRoom
的书自动归还到 BorrowReturnOffice
,并立即对“阅读不还”用户罚分;
对保留期到了却没取的预约,罚分并移出 AppointmentOffice
。
借阅 / 预约 / 取书 / 阅读 / 归还 的授权与移动
借阅:
先检查 User.canBorrow(isbn)
(借阅权限查询)。
再从 Bookshelf
或 HotBookshelf
请求一个副本。
预约:
先检查 User.canOrder(isbn)
(预约权限查询);
如果成功,创建 Reservation
并记录到 appointmentOffice
;命令执行后整理时真正搬书。
取书:只可从 AppointmentOffice
取指定给自己的那本副本。
阅读 / 归还:同借阅/还书对称,只是对象是 ReadingRoom
。
信用分
在用户还书时、顺利阅读并当天归还时加分;逾期/不取罚分。
User
内封装了加减分的限界(0–180)逻辑。
在本单元中,始终将 UML 模型与 Java 代码紧密绑定:在类图中定义的每一个核心类——如 Library
、User
、Bookshelf
、AppointmentOffice
、BorrowReturnOffice
、ReadingRoom
、Reservation
——都在代码中有对应的 Java 类,属性字段和方法签名在两者之间保持了一一对应。
为了确保设计与实现不脱节,在 StarUML 中为每个公共方法和关联关系都标注了精确的名称、参数和可见性,这些信息在编码时被直接照搬进 Java 类定义,从而保证了 UML 模型与代码结构的高度一致性。状态图中的每条状态迁移都对应于代码中带有 @Trigger
注解的方法,注解里指定的 from
、to
状态与图中节点名称完全对齐,Guard 条件的变量也都直接映射到相应类的成员变量,确保运行时的状态转换逻辑能够严格按照模型执行。顺序图则通过 @SendMessage
注解完成了设计与实现的桥接:模型里“orderNewBook”和“getOrderedBook”这样的消息路径,在代码中以同名的注解方法出现,Lifeline 的类名与 Java 类保持一致,消息发送与接收的方法调用序列在调试时可以与顺序图一一核对。
通过这种追踪方式,不仅使得 UML 文档能够直接驱动实现,也方便在后期维护时快速定位设计意图与代码落地之间的差异,实现了设计与实现的闭环。
在本次单元的设计与实现过程中,我尝试借助大语言模型(LLM)来辅助架构设计与文档撰写,收获了以下几点经验:
分阶段询问(阶段化提问)
需求梳理阶段
提问示例:“本系统涉及哪些业务场景?请列出所有用户操作与约束规则。”,从而快速生成借阅/预约/阅读等功能清单,确保对全局需求无遗漏。架构草案阶段
提问示例:“基于上述场景,建议哪些核心类?它们的主要属性和方法是什么?”,从而得到初步的类与职责划分,用作 UML 类图的元数据。交互与状态阶段
提问示例:“请分别给出预约取书的状态机和时序图伪代码,标注 Trigger、Guard 与消息名。”,获得清晰的状态转换与消息流程示例,能直接映射到@Trigger
/@SendMessage
注解。给定思维链(提示链式思考)
在 prompt 中嵌入“是什么、为什么、怎么做”的思考框架:
是什么:让模型先输出“核心实体与关系”;为什么:紧接着让模型说明“这么设计的原因与优势”;怎么做:最后引导模型给出“具体方法签名或伪代码”。这样能强化模型输出的逻辑顺序,减少遗漏和跳跃。
加入反思检查(输出审核与自检)
自我提问:在 prompt 中要求模型“对刚才的输出做一次自我审阅,指出可能存在的歧义或遗漏”。
一致性对比:提示模型“将上述伪代码与已有 UML 类图中的方法名做比对,列出不一致处并给出修正建议”。
第一单元主要任务是表达式化简。这一单元主要采用了递归下降的方法,采用了形式化思路(从 BNF 文法出发,明确“因子–项–表达式”三层结构,并提炼出 Expression
、Term
、Factor
、FunctionCall
等核心类)以及层次化分解(把复杂算子(如链式法则、乘法法则)拆解到对应类中,实现模块化和可扩展性)。
第二单元是实现一个电梯调度系统。除了多线程调度的相关知识,主要学到了各种设计模式,比如状态设计 (把电梯运行流程(Arrive→Open→In/Out→Close
)抽象成状态机,用 State 对象管理生命周期)、策略模式(把“目的选层”“捎带”“优先级调度”等算法封装到可替换的策略类,学习了低耦合设计)、生产者-消费者模式(解耦“请求产生”与“请求执行”两条职责线实现指责分离并提高程序可扩展性)。
第三单元是实现一个社交网络。主要学到了JML规格设计以及对系统的性能优化设计。这一单元学到了规格驱动(先读懂并严格遵守 requires/ensures/pure/assignable 约束,保证实现完全符合接口规范)以及性能意识(实现前后预估/验证时间空间复杂度,在规格正确基础上再优化,例如计算三元环的方式暴力使用三层循环,一定会超时,实现维护则可以降低查询时的复杂度)。
第四单元则是实现一个图书馆系统。主要是体会到了好的设计对与开发的好处。正向建模(先用 StarUML 画类图(职责、关联)、状态图(书籍/事务生命周期)、顺序图(部门与用户交互))迭代开发(每次作业增量引入“热门书架策略”“阅读归还”“信用分规则”“借阅期限规则”,体会到了好的建模设计对于迭代设计的好处)。
5. 测试思维的演进
第一单元 主要采用了黑盒测试,聚焦“表达式展开与求导”这一核心功能,将其视为一个纯函数输入→输出的黑盒。随机生成大量数学表达式(包括多项式、三角函数、嵌套自定义函数、导数算子等),用 Sympy 等成熟库计算参考结果,和自己程序的输出做逐项比对。
第二单元采用并发工具,重点对线程安全进行检查电梯系统是多线程环境,除了功能正确性,更需要关注线程安全和状态机一致性。使用检测线程的工具工具(如 ThreadMXBean)扫描锁使用与共享变量访问,检查竞态条件和死锁隐患,并锻炼了对“运行时状态快照”与“日志回放”调试并发程序的能力。
第三单元主要采用JML 规格化单元测试,借助 JML 把方法的前置/后置条件和可变性明确下来,就能够用单元测试精确验证。针对每个接口方法,根据 JML 的 requires
/ensures
/assignable
编写对应的 JUnit 测试用例;不仅验证“正确返回值”,还要检查“调用前后状态不违背 pure/assignable 约束”、边界异常抛出是否符合预期。
第四单元主要关注情景与边界检查。图书馆系统功能繁多,重点在于各种状态(书架/热门架/预约处/借还处/阅览室/用户手中)和用户信用分策略的交叉影响。设计信用分边界用例(0、39、59、99、180),分别尝试借阅/预约/阅读不同类别的书。构造书籍在多位置间流转场景:多用户对同 ISBN 的预约→整理→取书→逾期未取→再次预约流程,以及同时存在热门与普通书架的搬迁逻辑。检查边界情况。
在这门面向对象课程中,我最大的收获是对 面向对象思想的系统理解与实践应用。我掌握了类、继承、多态等基础概念,能熟练运用常见设计模式和 UML 工具辅助设计,并通过多次项目实践体会到 高内聚、低耦合 设计的价值。同时,我学习了 SOLID 原则,为模块化和可维护性打下基础。
更重要的是,我逐渐形成了系统性思维,学会从全局视角思考设计与实现的平衡。无论是先导项目中的迭代优化,还是多线程调度或复杂状态管理的项目,都让我深刻体会到:合理的设计先行,才能避免无谓的重构与开发障碍。这门课不仅提升了我的编码能力,更塑造了我作为软件设计者的思维方式。