OO第四单元&课程总结

曾骋-24371408 2026-06-19 23:50:27

一、本单元的正向建模与开发

第四单元要求先分析图书馆业务、绘制类图,再根据模型实现代码。我从题目中的名词和动作出发,识别出 BookBookCopyUser 等实体对象,书架、借还处、预约处等场所对象,以及负责业务协调的 Library 和负责图书移动的 LibraryManager。这种建模过程先确定了系统中的稳定概念和职责边界,避免把所有流程集中在一个类中。

三次作业的迭代也体现了模型的扩展方式。第二次作业新增阅读、评分和精品书架,因此增加了 ReadingRoomScoreTreasuredBookshelf;第三次作业新增信用分、借阅期限和续订,这些功能属于用户或图书副本自身的状态,因此主要扩展 UserBookCopyLibrary,没有继续增加领域类。这让我认识到,新需求是否需要新类,应由业务职责决定,而不是由功能数量决定。

两阶类图在正向建模中承担不同作用。第一阶类图是编码前的设计假设,用来明确类、属性、方法、关联和多重性;第二阶类图是实现后的设计审计,用来检查预设计是否真正适合代码。两者构成“需求分析—预设计—实现—最终模型—设计复查”的闭环。两张图可以存在差异,但每一处变化都应能够由实际业务和代码结构解释。

具体来说,第一阶类图迫使我在编码前回答一些关键问题,例如图书副本由谁持有、预约信息保存在哪里、各个场所是独立管理图书还是由统一对象协调。如果这些问题没有提前明确,代码很容易变成大量集合和条件分支。第二阶类图则用于重新检查实际形成的依赖,删除没有必要的关联,补充实现后才能确定的方法和多重性。因此,第一阶类图关注“准备怎样实现”,第二阶类图关注“最终是否以合理方式实现”。

二、本单元架构设计与代码—UML 追踪关系

最终系统以 Library 为业务入口,以 LibraryManager 管理各个场所,以 BookCopyUser 保存核心状态。Main 分发输入请求,Library 判断借阅、预约、阅读、信用和期限等规则,LibraryManager 统一执行图书移动,BookCopy.recordMove() 更新位置并记录移动轨迹。这样将业务判断、容器维护和状态记录分离开来。

代码与 UML 之间存在明确追踪关系:类图中的类、属性、方法和关联能够映射到对应代码;状态图中的书架、阅览室、借还处、预约处和用户状态对应 BookCopy 的位置变化,并由带有 @Trigger 的方法触发;顺序图中的 orderNewBookhandlePickgetOrderedBook 等消息对应真实方法及 @SendMessage 注解,描述预约和取书的调用顺序。

追踪关系不只是名称相同,还要求对象所有权、方法可见性、状态迁移和类间关联保持一致。最终架构仍有改进空间,例如 Library 承担的流程较多,未来可以进一步拆分预约、信用结算和整理策略。此外,重复排序图书副本曾导致测试超时,后来通过预先维护有序副本列表解决,也说明正确的领域模型仍需要配合合适的数据结构和复杂度设计。

整理流程最能体现这一架构的协作方式。开馆或闭馆时,系统需要整理借还处、阅览室和预约处中的图书,同时处理预约保留期限,并根据 ISBN 的平均评分选择普通书架或精品书架。Library 负责判断业务条件,LibraryManager 负责移动图书,BookCopy 负责记录当前位置和移动轨迹。三者分工后,业务规则、容器一致性和副本状态不会混杂在同一个方法中。

第三次作业中的信用和期限功能也能沿原有架构自然落地。信用分由 User 维护,借阅应还日期由具体的 BookCopy 维护,Library 在闭馆、还书和续订时触发规则。这种对应关系说明 UML 中的职责划分确实指导了代码扩展,而不是在功能完成后才勉强寻找映射。

三、如何引导大模型完成复杂架构设计

使用大模型辅助本单元作业时,最有效的方式不是直接要求它“设计整个系统”,而是让它分阶段完成任务。首先提供完整题面、现有代码、官方包、UML 文件和评测反馈,并要求先阅读真实 API;随后让模型整理领域对象、所有权、状态、不变量和新增需求,再讨论职责划分;最后按照“代码实现—编译测试—性能检查—同步 UML—验证追踪关系”的顺序执行。

对于复杂规则,可以让大模型先整理请求的前置条件、成功效果、失败效果和状态迁移,再开始编码。收到评测反馈时,也应针对具体规则修改,而不是立即重构整个系统。代码必须经过编译、样例和压力测试,UML 则需要检查 JSON、引用完整性并在 StarUML 中实际查看。大模型适合搜索代码、整理规则和完成机械同步,但抽象是否合理、修改是否必要以及验证是否充分,仍需要由人判断。

本次实践中,较有效的协作方式是明确阶段边界。例如第三次迭代时,先让大模型阅读当前代码和官方包,确认信用查询、续订命令及输出接口,再实现业务规则;代码通过测试后,才同步最终类图并补充状态图和顺序图。这样可以避免模型一边猜测接口一边修改多种文件,也便于判断问题来自业务实现还是 UML 表达。

此外,提示中应说明哪些文件可以修改、哪些现有结构需要保留、哪些评测规则必须满足,并要求每项新增抽象都说明业务理由。对模型输出也不能只做文本检查:Java 代码需要真实编译运行,性能优化前后要比较输出,.mdj 文件不仅要能解析,还要在 StarUML 画布中真正显示。只有把生成任务转化为可验证的工程流程,大模型才更适合参与复杂架构设计。

四、四个单元中架构设计思维的演进

第一单元中,我通过 LexerParser、AST 和化简器完成表达式处理,开始理解“先建立结构,再执行操作”。第二单元的多线程电梯让我关注线程边界、共享资源和对象生命周期,认识到时间顺序也是架构的一部分。第三单元通过 JML 规格强调前置条件、异常行为和状态不变性,使架构从对象协作进一步发展到契约约束。

第一单元的对象主要对应语法概念,架构重点是将词法分析、语法分析和计算过程分离。到了第二单元,请求会在输入线程、调度器、等待队列和电梯之间迁移,对象之间不再只有静态调用,还存在并发访问和生命周期问题。第三单元保持 NetworkUserVideo 等核心领域类稳定,在其上持续增加关注、传播、评论和推荐功能,使我体会到稳定抽象对多次迭代的重要性。

第四单元将这些能力统一到正向建模中:类图描述静态职责,状态图描述对象生命周期,顺序图描述对象交互,代码实现模型承诺。我的关注点逐渐从“功能能否实现”转变为“变化是否被封装在合适对象中”“不变量能否得到维护”以及“模型、代码和测试能否相互追踪”。

回顾这一过程,我不再用类的数量判断设计是否面向对象,而更关注职责是否集中、变化是否局部化。例如评分适合形成独立对象,是因为它具有自己的数据和计算规则;信用分不需要形成新的管理类,是因为它本来就是用户状态。这样的判断比机械地套用设计模式更接近真正的架构设计。

五、四个单元中测试思维的演进

第一单元主要通过不同表达式检查语法覆盖和计算结果;第二单元加入并发后,测试开始关注输出时序、线程退出、资源竞争和死锁;第三单元让我学会从 JML 规格推导正常分支、异常分支、边界值、帧条件和查询纯度;第四单元则进一步覆盖业务事件序列、日期边界、性能限制以及 UML 与代码的一致性。

测试对象也逐渐从单次输入输出扩展到完整状态过程。第三单元中,查询操作不仅要返回正确结果,还要保证网络状态不被修改;第四单元中,借阅、预约、送达、取书、过期和信用扣分需要放在连续日期中共同验证。对于代码优化,我也开始比较修改前后的完整输出,确认性能提升没有改变外部行为。

因此,我的测试目标从“验证几个样例正确”逐渐转变为“主动发现设计薄弱点”。测试不仅检查结果,也检查状态是否被意外修改、复杂度是否可接受,以及重构前后行为是否一致。

现在面对一个新需求,我会先从规则中提取正常路径、失败路径和时间边界,再设计连续事件场景,而不是只测试单条指令。这样的测试更容易发现方法之间的状态衔接问题,也能反过来帮助我判断职责划分是否合理。

六、课程收获

从 AST、线程协作、JML 规格到 UML 正向建模,我逐渐形成了“先寻找结构,再编写流程;先明确不变量,再处理分支;先建立验证证据,再确认完成”的工程习惯。相比某个具体算法或 API,这种分析复杂问题并持续验证设计的能力,是我在课程中最重要的收获。让我认识到,面向对象并不是简单地增加类,而是建立能够承载变化的模型。封装用于维护不变量,规格用于约束行为,类图、状态图和顺序图则分别表达结构、生命周期和交互过程。

课程也让我更能接受设计需要反复修正。预设计的价值不在于一次得到完美答案,而在于提供可以讨论和验证的起点;最终模型的价值则在于记录经过实现检验后的结构。以后面对更大的项目,我会继续保留这种让需求、模型、代码和测试相互反馈的工作方式。

...全文
4 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

308

社区成员

发帖
与我相关
我的任务
社区描述
2026年北航面向对象设计与构造
java 高校
社区管理员
  • 孙琦航
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧