2026 OO 课程总结

王竣翔-24373372 2026-06-19 12:59:01

2026 OO 课程总结

一、正向建模与两阶类图的作用

第四单元以图书馆管理系统为背景,三次作业依次加入基础借还与预约、阅读与评分、信用分与借阅期限等功能。我的开发过程不再从编写 Main 和请求分支开始,而是先从需求中提取图书副本、用户、地点、预约、借阅记录和规则策略等领域概念,再确定数据归属、公开行为和依赖方向。正向建模使一些容易被实现细节掩盖的问题提前暴露,例如副本状态究竟由地点还是副本维护、整理流程和用户请求是否可以共享移动入口、预约和借阅记录由谁负责结束生命周期。

一阶类图 uml_pre.mdj 的主要作用是给实现建立设计基线。它不需要提前列出所有 getter 和辅助函数,但必须覆盖稳定的核心类、重要属性、主要业务方法以及继承和关联关系。通过一阶类图,我能够在编码前检查 LibraryManager 是否过重、地点类是否具有共同抽象、规则是否值得独立成策略类,并为信用和借阅期限等变化预留位置。它使代码开发从“遇到功能再加字段”转变为“依据职责逐步填充对象行为”。

二阶类图 uml_ultimate.mdj 则用于让设计在实现之后收敛。编码过程中会出现一阶图没有预见的辅助方法、输入输出适配和记录字段,也可能发现某些原设计没有必要。二阶图需要吸收这些经过实践验证的变化,同时保持核心实体和依赖方向稳定。因此,两阶类图不是草稿和答案的关系,而是设计假设与实现反馈之间的闭环;差异本身并不可怕,无法解释差异才说明正向建模没有真正发挥作用。

二、本单元架构及代码与 UML 的追踪关系

第一次作业中,LibraryManager 直接持有书架、预约处、借还处、用户表和副本表,并实现借阅、归还、预约和取书;RequestProcessor 负责官方输入输出,ArrangeService 负责开闭馆整理,BorrowLimitChecker 封装 B/C 类借阅限制。这一版形成了图书、副本、用户、预约和地点的基本领域骨架,但管理器同时承担数据存储、业务判断和流程调度,职责仍然较集中。

第二次作业加入阅览室、评分和精品书架后,地点与移动状态增多,我将系统重构为以 Library 为领域聚合、LibraryManager 为外层协调器、RequestHandler 为请求服务、ArrangeService 为时间流程服务的结构。Location 成为各地点的公共父类,BookState 显式表示副本状态,BookCopy.moveTo() 成为状态变化的统一入口。第三次作业再加入 CreditPolicyLoanPolicyCreditRecordLoanRecordRenewService,将信用奖惩、期限计算、逾期判断和续订规则从请求处理器中分离,使管理器没有继续膨胀。

最终 UML 与代码之间可以建立明确追踪:类图中的关联对应 Java 成员变量,继承关系对应 extends,操作对应类中的方法;状态图中的状态对应 BookState,状态字段对应 BookCopy.state,迁移触发器对应 moveTo();顺序图中的预约和取书消息对应 orderNewBookregisterOrderpickBookgetOrderedBook 等方法。需求中的每条关键规则都应当能够追踪到模型元素和代码落点,而代码中的核心设计单元也应当能在二阶类图中找到对应表达。

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

大模型在复杂场景中最适合承担需求整理和方案评审工作。面对篇幅很长的题目,可以先要求它提取领域词汇、用例、前置条件、后置条件、失败条件和全局不变量,而不是直接生成完整类图和代码。例如图书数量守恒、一个副本只能位于一个地点、信用分具有上下界、逾期处罚不能重复等约束,都会直接影响对象的数据归属和方法设计。只有先固定这些事实,后续的类划分才不会建立在模型自行补充的规则上。

在得到领域信息后,应继续引导模型输出职责表,说明每个候选类拥有的数据、允许修改的状态、公开行为和依赖对象,并明确限制依赖方向。可以要求输入输出层不得侵入领域层,地点类不能反向控制总管理器,副本状态只能通过统一入口修改,策略规则不能散落在多个请求方法中。之后再让模型建立“需求—类—方法—状态迁移—顺序消息”的追踪矩阵,并逐个场景实现,这比一次生成几十个类更容易审查和纠错。

本单元的实际体验表明,大模型能够较快识别 CreditPolicyLoanRecordRenewService 等抽象,也能帮助检查职责是否重叠,但它并不可靠地理解 StarUML 的序列化细节。模型可能生成结构看似完整、实际存在重复 _id、断引用、非法类型或错误层级的 mdj 文件。因此,大模型输出必须经过语义校验、结构校验和工具校验,包括人工复核规则、编译与样例测试、StarUML 打开检查以及图代码一致性评测。大模型应当作为设计协作者,而不是未经验证的制品生成器。

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

第一单元处理表达式时,我的关注点从字符串替换逐渐转向 Lexer—Parser—Expr/Term/Factor—Polynomial 的对象层次。不同因子通过 Factor 接口和具体实现表达,新增函数、递归函数、求导和选择结构时,可以增加新的对象行为,而不必在一个大函数中持续增加类型分支。这一阶段让我理解了多态和递归组合的价值,也认识到“拆成多个类”并不自动意味着职责合理,复杂化简逻辑仍需要独立抽象。

第二单元进入并发电梯后,架构设计的重点从对象层次转向共享状态和线程协作。最终系统使用 Dispatcher 进行全局任务分配,ElevatorThread 负责单梯执行,RequestPool 提供同步请求容器,LookStrategy 生成运行建议,ShaftController 管理维护、升级和回收状态。我开始关注哪些字段由哪个线程修改、等待和唤醒基于什么条件、结束判定如何覆盖所有未完成任务,以及策略计算如何避免直接操作共享状态。

第三单元的 JML 规格使架构进一步受到契约约束。NetworkUserVideo 的职责需要符合接口的前后置条件、异常和副作用范围,图查询算法被抽到 NetworkQueries,派生统计量则使用增量维护或缓存失效。第四单元又把设计推进到代码之前,要求使用类图、状态图和顺序图分别表达静态结构、生命周期和交互过程。四个单元中,我的思维经历了从过程分解、对象多态、并发协作、契约驱动到模型驱动和全链路追踪的演进。

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

第一单元的表达式输出形式不唯一,因此测试不能只比较字符串,而要关注数学等价性。我逐渐开始覆盖嵌套括号、连续符号、递归函数、指数边界和求导组合,并通过代入数值或符号化结果判断语义是否一致。这一阶段让我第一次明确区分格式合法、结果等价和复杂度可接受三个测试目标,也开始从样例测试转向边界和随机测试。

第二单元中,并发电梯同样没有唯一合法输出,测试重点转向时序和不变量:乘客必须先进入后离开,最终到达目标层,载重不能超限,维护和升级期间不能违规运行,所有线程必须最终结束。我使用带超时的混合压力数据检查死锁、竞态和活性问题。第三单元则可以直接从 JML 的 requires、ensures、异常优先级和副作用范围提取测试点,同时覆盖图算法的不可达、并列排序、冷启动和缓存失效场景。

第四单元把测试对象从运行结果扩展到了设计制品。除了借阅、预约、信用和续订场景,还要检查类、接口和枚举是否与源码一致,状态是否可达、Guard 是否互斥,Message 路径是否连续,Lifeline 是否对应代码类,以及模型名称、文件位置和引用层级是否符合要求。我的测试思维由输入输出驱动逐步转向不变量驱动、契约驱动和多制品一致性驱动,编译通过不再等于任务完成。

六、课程收获

这门课程让我认识到,面向对象的核心不是增加类的数量,而是识别稳定职责、隔离变化并维护不变量。多态适合处理类型变化,策略对象适合封装规则变化,记录对象适合保存具有生命周期的业务事实,服务对象适合组织跨实体流程;如果新增需求仍然需要同时修改大量无关类,就说明变化没有被放在正确的抽象位置。与此同时,任何重要状态都应有明确所有者和统一修改入口,这一原则在并发电梯和图书副本管理中都十分关键。

我也逐渐理解,规格、UML 和测试并不是编码完成后的附属材料。JML 能帮助明确合法输入、异常顺序和副作用,UML 能在编码前暴露职责冲突和依赖问题,测试则把这些约束落实为可重复验证的证据。重构也不再只是把长方法拆短,而是调整所有权、依赖方向和变化边界,使系统更容易解释、验证和继续扩展。

经过四个单元,我不仅提高了 Java、并发、图算法和建模工具的使用能力,更形成了先分析需求变化和全局约束、再设计对象协作、最后用规格、测试和模型验证设计的工程习惯。大模型能够提高需求整理和方案比较的效率,但最终质量仍取决于开发者能否识别模型的假设、发现工具格式问题并建立完整验证闭环。这种对设计理由和验证证据的重视,是我在整门课程中最重要的收获。

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

309

社区成员

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

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