2026面向对象第四次博客作业

张哲元24371019 2026-06-19 22:00:19

2026面向对象第四次博客作业

一、总结本单元所实践的正向建模与开发,重点分析两阶类图在正向建模过程中的作用

第四单元最大的变化,是开发流程从“先写代码再补结构”转向了“先用模型组织问题,再让代码落地模型”。本单元图书馆系统的需求在简单的增删查改基础上,逐步添加了借阅限制、预约保留、精品书架、信用分、评价等一系列相互影响的规则。如果直接从输入输出开始堆逻辑,很容易把所有业务塞进一个大类里,后期一旦新增规则,代码和图都十分复杂。

我在正向建模时,首先从需求中的名词和动作抽取领域对象:图书对应 Book,用户对应 User,普通书架、精品书架、预约处、借还处、阅读室抽象为不同的区域类Area,系统调度由 LibraryManager 统一负责,输入解析由 InputParser 适配官方包,动作请求和查询请求则通过 RequestActionRequestQueryRequestActionType 表达。这样做的核心不是提前决定每个对象的职责,方便进行架构管理。

两阶类图在这个过程中起到了不同作用。第一阶段类图是开发前的架构草稿,它重点回答“系统有哪些稳定概念”“对象之间如何协作”“哪些规则应该被封装到哪个类里”。例如,在第一次迭代中,只需要处理借书、还书、预约、取书、查询,类图就可以先稳定出 BookUserLibraryManagerBookshelfAppointmentOfficeBorrowReturnOffice 等核心结构。

第二阶段类图则承担了“实现后的追踪和校准”作用。随着第二、三次迭代引入阅读室、评分、精品书架、信用分、续借、逾期扣分等新内容,原来的模型会发生漂移。最终类图需要把这些实际设计同步进去,例如 Book 中的预约信息、到期时间、扣分状态,User 中的持有图书、当前阅读图书、信用分,GradeOffice 中的评分和精品书判断。这个阶段的类图检查代码有没有偏离最初职责划分,也检查 UML 是否真实反映了代码。

因此,两阶类图的价值在于:第一阶段帮助我从需求中建立架构抽象,第二阶段帮助我反查代码是否符合最初的架构设计。两者结合起来,正好形成了正向建模中从需求到模型、从模型到代码、再从代码回到模型的一次闭环。

二、总结本单元作业的架构设计,并对比分析最终的代码设计和 UML 模型设计之间的追踪关系

本单元最终代码采用的是以 LibraryManager 为中心的架构。LibraryManager 持有各类区域对象、用户集合、图书集合、预约队列和输入解析器,负责根据官方包输入分发到不同业务流程。它本身不应该变成单纯的数据类,而是承担“图书馆业务调度中心”的角色:开馆、闭馆、整理、借阅、预约、取书等等,都由它进行流程控制。

在功能对象方面,Book 代表具体副本,负责记录 ISBN、副本号、当前位置、预约用户、预约保留期限、借阅到期日、逾期扣分、移动轨迹等信息。User 代表读者,负责维护自己持有的书、当前阅读的书、未完成预约和信用分,并提供能否借阅、能否预约、能否阅读等约束判断。Area 作为区域抽象,统一描述“某个地点持有哪些书”,其子类包括 BookshelfTreasuredBookshelfBorrowReturnOfficeAppointmentOfficeReadingRoom。这种设计使状态图中的图书位置可以自然映射到代码中的区域对象。

请求处理方面,InputParser 负责把官方包中的输入适配为内部请求对象。RequestActionRequestQueryRequestActionType 则把交互信息结构化,将枚举类传递给LibraryManagerGradeOffice 负责评分和精品书判断,使精品书架的变化不需要散落在借阅、整理、查询等多个流程里。

UML 与代码之间的追踪关系主要体现在以下几个方面:

UML 元素代码对应追踪关系
类图中的 LibraryManagerLibraryManager.java对应系统总控类,关联用户、图书、各区域、解析器和评分处
类图中的 BookBook.java对应具体图书副本,承载状态、预约、期限、轨迹等信息
类图中的 UserUser.java对应读者状态,维护持有书、阅读书、预约和信用分
类图中的 Area 及子类AreaBookshelfTreasuredBookshelfBorrowReturnOfficeAppointmentOfficeReadingRoom对应状态图中的图书位置
类图中的请求类RequestActionRequestQueryRequestActionType对应输入命令到业务分发的中间模型
类图中的 GradeOfficeGradeOffice.java对应评分、平均分、精品书判断逻辑

状态图与代码的追踪重点是“图书位置变化”,其中的迁移必须能在代码中找到真实触发方法,例如借阅使图书从书架到用户,预约整理使图书从书架或借还处到预约处,取书使图书从预约处到用户,还书使图书从用户到借还处,阅读使图书从书架到阅读室,归还阅读书使图书从阅读室到借还处,整理再根据评分和预约情况移动到不同区域。

顺序图与代码运行过程中时序逻辑的追踪要求更严格。第三次迭代中,顺序图要求覆盖预约和取书场景,起始消息必须名为 orderNewBook,结束消息必须名为 getOrderedBook;lifeline 必须对应程序中的真实类,message 必须对应源类或目标类中的真实方法。让真实业务方法承担对应含义,例如将预约流程中的真实入口设计为 orderNewBook,将取书流程中的真实入口设计为 getOrderedBook,可以帮我更好地梳理各个类的联系,并用信息传递的视角对程序进行动态分析。

三、根据使用大模型辅助正向建模的体验,总结分析如何引导大模型在复杂场景中完成架构设计任务

这次使用大模型辅助建模给我的最大感受是:大模型适合做“结构化整理”和“规则一致性检查”,但不能放任它自由发挥。图书馆系统的规则很多,而且规则之间有依赖,例如信用分会影响借阅、预约、阅读权限;预约成功和预约书送达不是同一个时刻;取书时不应该重新检查当前信用分是否大于 80,而应该检查取书后的持书数量限制;一次整理中同一本书不能被移动两次。对于这类复杂场景,如果只让大模型“帮我画 UML”,它很容易画出看似完整但和代码、评测规则不一致的模型。

比较有效的引导方式,是把任务拆成几个层次。第一步让它从需求中抽取领域实体、核心状态和业务动作,例如图书、用户、区域、预约、信用分、评分、整理。第二步和它共同讨论职责分配,而不是直接给类图,例如哪些状态应该放在 Book,哪些约束应该放在 User,哪些流程应该由 LibraryManager 调度。第三步再要求它检查 UML 与代码的一致性,例如类图中的类是否真实存在,顺序图 lifeline 是否对应真实类,message 是否对应真实方法,状态图触发器是否对应实际迁移方法。第四步要求进行充分测试,避免在强测暴毙的可能性。

在具体评测中,我遇到了部分类图方法名字不对应的问题,修复时候大模型可能会凭空捏造一些不存在的空方法。需要明确告诉大模型“不要为了满足 UML 检查而补空方法”。因为评测关注的是模型和代码的对应关系,但真正合理的做法不是凭空添加 orderNewBook 这类空壳,而是把已有预约业务的真实入口调整成这个方法名,让 UML 消息和代码行为自然对应。

四、总结自己在四个单元中架构设计思维的演进

第一单元表达式处理让我第一次明显感受到“语法结构”和“计算逻辑”应该分离。最开始递归下降解析、表达式树和多项式化简混在一起还能跑,但随着自定义函数、嵌套调用、求导和化简规则增加,如果所有逻辑都压进 toPoly 一类的方法中,就会出现共享引用、深拷贝、符号处理等问题。后期我逐渐把 Lexer、Parser、AST“语法结构”构建,与Poly、Mono 的“计算逻辑”具体生成分开,解析语法树之后都统一使用Poly类进行管理,从而避免了函数展开、求导等复杂运算难以支持的问题。

第二单元电梯作业把架构问题从“单对象计算”推进到了“并发协作”。请求输入、调度器、等待队列、电梯线程、策略、维护和换乘之间存在明显的数据流。我开始用生产者-消费者的方式思考系统,把 InputThread -> DisQueue -> DisThread -> EleQueue -> EleThread 作为主线,再用策略对象和虚拟队列辅助调度。这个单元让我认识到,并发程序的架构重点不只是功能拆分,还包括锁的边界、共享资源的归属、线程之间的关闭协议和异常时序。

第三单元 JML 则把我的思维从“怎么写”提高到了“严格符合规格要求”,这也是明确需求边界。JML 中的 requiresensuresassignablepuresignals 把方法行为边界写得很清楚,也迫使我关注异常优先级、副作用范围、查询方法纯度和数据结构复杂度。我在这个单元中明显感觉到大模型在面对JML需求时产生的幻觉大大减少,也启发我要写提示词时要参考JML的思路,将输入格式、输出需求和过程限制都讲清楚。此外还要注意,架构设计不只是简单“翻译”JML,还包括如何在不破坏规格的前提下实现性能优化。

第四单元 UML 则进一步把设计前置。前几个单元我更多是从代码出发,再总结结构;而本单元要求先画类图,再实现代码,后续还要用状态图和顺序图追踪行为。我的架构思维也从“把功能做出来”逐渐变成“让需求、模型、代码和测试互相约束”。尤其是两阶类图、状态图、顺序图的连续要求,让我意识到”敏捷开发“和”瀑布模型“的辩证关系:好的模型可以提前暴露职责不清的问题,最终模型又能反向检查代码有没有偏离原设计。

五、总结自己在四个单元中测试思维的演进

第一单元的测试主要是黑盒和边界构造。表达式作业的难点在于符号、括号、嵌套、函数替换、求导和化简,所以我更多关注输入形式的覆盖,例如多层括号、连续正负号、函数嵌套、同类项合并、零项、幂次边界等。同时也会用对拍或脚本辅助判断等价性。这个阶段的测试思维还是“尽量喂多样化、复杂输入,看输出对不对”。事实上,我发现很多程序更多需要针对单点进行突破(比如连续三个符号),盲目构造样例有时候效果并不理想。

第二单元开始,测试重点转向时序和并发。电梯系统的错误不一定来自某条请求本身,而可能来自请求组合、线程切换、维护时机、调度策略和锁竞争。我开始通过构造极端时间间隔、集中请求、维护请求、换乘请求来压测系统,并且依赖日志分析程序运行过程。这个单元让我认识到,有些 bug 不是靠看评测机大量刷数据能发现的,必须针对可能出错的点(比如体重超重,大量请求同时产生等极端情况)手动构造数据

第三单元的 JML 让我开始从规格生成测试。每个方法的前置条件、后置条件、异常条件和副作用范围都可以转化为测试点。比如测试异常优先级时,不只是看会不会抛异常,还要看多个错误同时存在时抛出的是否是规定异常;测试 assignable 时,不只是看返回值,还要保存调用前快照,检查不该修改的对象有没有被修改。这个阶段写JUnit测试反而耗费了大量时间,并且与大模型交流的效果也不好,我认为核心还是需要理解assignment和pure方法的限制,从这些不变量入手、全面构建测试。

第四单元的测试可以结合状态图和顺序图进行,图书馆系统有大量状态流转,单个输出正确并不代表整体合法。我需要检查图书总数是否守恒、移动轨迹是否连续、一次整理中同一本书是否只移动一次、预约过期后是否取消用户预约、取书是否只取被保留给该用户的副本、信用分变化是否发生在正确时间点、逾期扣分是否只扣一次。之前实际调试中出现过一次整理中同一本书被过期处理和预约满足重复移动的问题,要注意检查每次状态变化背后的规则(结合状态图)。

总体来看,我的测试思维从第一单元的“输入输出覆盖”,发展到第二单元的“过程和时序检查”,再到第三单元的“契约验证”,最后到第四单元的“模型状态和业务不变量验证”。系统越复杂,越不能只依赖样例和评测机随机生成,必须建立自己的检查标准。

六、总结自己的课程收获

这门课给我最大的收获,是让我真正理解了面向对象并不只是类与对象的简单封装,更在于架构设计和思维的严谨性。面向对象的核心是责任分配、边界控制和变化管理。第一单元中,如果表达式解析、函数替换和多项式化简混在一起,后续扩展就会痛苦;第二单元中,如果线程之间共享资源边界不清,功能正确也可能被时序击穿;第三单元中,如果方法契约不清,数据结构优化很容易破坏行为;第四单元中,如果 UML 模型和代码不能追踪,设计文档就会变成形式。

我也逐渐接受了迭代中重构的必要性,很多架构问题不是第一次就能完美预判,但好的设计应该允许后续需求接入,即敏捷开发和瀑布模型的平衡。例如图书馆系统从普通借还扩展到阅读室、评分、精品书架、信用分和续借时,如果一开始就把“图书位置”抽象成区域,把“用户权限”集中在用户状态中,把“业务流程”集中在管理器中,后续改动就会更可控。相反,如果为了某个测试点临时堆判断,下一次迭代就会付出更多代价。测试方面,我从“过样例”逐渐转向“找不变量”。表达式的不变量是数学等价,电梯的不变量是请求不丢失和运行规则不被破坏,JML 的不变量是契约成立,UML 图书馆的不变量是状态迁移合法、图书数量守恒、模型和代码一致。这个变化让我意识到,测试不是开发结束后的补丁,而是理解系统的一种方式。

此外,我认为老师和课程组对于大模型的教学十分用心,老师十分鼓励我们利用充分体验和挖掘大模型最先进的能力,课程组也提供了利用大模型的迭代建议等。经过一学期的学习和使用,我也更加理性的认识了大模型对于未来的影响。大模型可以帮助整理需求、发现遗漏、生成测试思路、审查 UML 与代码的一致性,甚至通过较好的提示词引导可以直接生成jml和uml的相关理解,形成较好的”自然语言-jml/uml-java“的转换链条。但前提是我必须给它明确的规格、代码上下文和判断标准。尤其在 OO 作业这种规则细、评测严的场景中,大模型不能替代我理解规则,也不能替代我决定架构取舍。如果过于依赖大模型,在强测数据的覆盖下往往会出现难以预期的问题,导致工程上的隐患。因此,即使它可以替代大量的重复工作(比如辅助重构),帮助我审查和讨论题目要求的细节,最终的架构设计和理解仍然需要自己的努力,也应当充分思考和构建测试。

总的来说,OO 课程让我从“把程序写出来”走向“把系统设计出来”。我对抽象、封装、迭代、契约、并发、建模和测试都有了更具体的认识。更重要的是,我开始习惯在写代码前先想对象职责,在调试时追踪状态变化,在扩展时维护结构稳定,在总结时反查模型和实现是否一致,形成了初步的工程思维。我想在大模型时代,这些能力远比java语言或者某次作业的细节更重要,也是这门课最有价值的地方。

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

308

社区成员

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

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