2026 面向对象设计与构造 Unit4及课程 总结

罗翔-24373373 2026-06-20 12:37:40

BUAA-OO 第四单元及全课程总结博客

一、正向建模与开发实践总结

对正向建模的理解

本单元的核心训练目标是正向建模,也就是先设计UML类图,再根据类图编写代码,而不是写完代码后反向生成图。这一顺序的改变,让我真正体会到了建模对于软件开发的指导意义。

三次作业的流程都要按照 需求分析 → 抽象核心实体 → 绘制一阶类图 → 编写代码 → 修正二阶类图 的顺序进行。

两阶类图的作用分析

一阶类图的作用是逼自己在动手写代码之前完成架构思考。以第十三次作业为例,在画一阶类图时,我需要回答几个关键问题:图书馆里有哪些地点?每个地点负责什么职责?用户和图书的关系是什么?这些问题在写代码时往往会被跳过,但画类图时必须逐一面对。

一阶类图的另一个价值是暴露模糊地带。例如在第一次作业中,我一开始没有独立设计 ArrangeStrategy 类,把整理逻辑全放在 Library 中,画类图时发现 Library 方法过多,职责混乱,于是在一阶阶段就做了拆分。这比在代码写完后重构要轻松得多。

二阶类图的作用是保持图与代码的一致性。编码过程中不可避免地会发现一阶设计的不足:例如第三次作业中,ArrangeStrategyarrange 方法参数超过了checkstyle限制,需要把 users 从参数改为构造函数注入的字段,这一变化就需要在二阶类图中同步体现。

二、架构设计总结与UML追踪关系分析

整体架构

三次作业的架构在同一骨架上迭代演进,核心分层如下:

Main(输入输出层)
  ↓
Library(业务协调层)
  ↓
地点类 + User(领域模型层)
  ↓
ArrangeStrategy(策略层)

地点类BookshelfTreasuredBookshelfBorrowReturnOfficeAppointmentOfficeReadingRoom)各自只负责本地点的图书存储和查询,不包含跨地点逻辑。

Library 作为业务协调层,持有所有地点类和用户集合,负责处理每一种用户请求,但不直接操作图书移动细节。

ArrangeStrategy 独立封装整理逻辑,通过构造函数注入 users,通过方法参数接收各地点类,实现了整理策略与业务逻辑的解耦。

代码与UML的追踪关系

UML元素代码对应
Library 持有 Bookshelf 等的关联线Library 中的 private final Bookshelf bookshelf 等字段
User --> Book 关联User.borrowedBooks : List<Book>User.dueDates : Map<Book, LocalDate>
AppointmentOffice --> Order 关联AppointmentOffice.pendingOrders : List<Order>
AppointmentOffice --> ReservationRecord 关联AppointmentOffice.reservedBooks : Map<String, ReservationRecord>
ArrangeStrategy ..> User 依赖ArrangeStrategy.users : Map<String, User>(构造注入)
Book --> BookState 关联Book.state : BookState
Book --> TraceRecord 关联Book.movingTrace : List<TraceRecord>

追踪关系中最值得一提的是 ArrangeStrategyUser 的关系变化。在初版设计中,users 作为 arrange 方法参数传入,导致参数超限;修改后改为构造注入字段,UML中从"依赖关系(虚线箭头)"升级为"关联关系(实线箭头)并新增 users 属性",这一变化在二阶类图中得到了同步体现,体现了图与代码的真实追踪。

三、大模型辅助正向建模的体验总结

有效的引导方式

在本单元中,我使用大模型辅助完成了架构设计和代码迭代。总结出以下几条有效的引导策略:

1. 先给需求再问架构

直接说"帮我写图书馆管理系统代码"会得到一个平铺直叙的单类实现。更好的做法是先描述业务场景,询问"应该抽象哪些类、各自的职责是什么",让模型先完成架构分析,再逐步细化到代码。

2. 明确约束条件

在要求输出架构时,提前说明限制条件可以避免后期大量返工。不过复杂场景中的约束往往不是一次能全部想到的,可以分轮补充。

3. 给出错误现象而非直接问修复方案

遇到bug时,提供具体的测试输入输出和错误信息,让模型自己追踪原因,比直接说"第X行有bug"更容易得到正确的根因分析。

4. 让模型解释设计决策

在得到架构方案后,追问"为什么这样设计""有没有其他方案",可以帮助自己真正理解设计。

局限性

大模型在复杂业务规则的细节上容易出错,例如本单元中逾期扣分的时机("借阅期限最后一日结束后"而不是"还书当天")、预约保留期的计算(开馆前整理和闭馆后整理的起算日不同)等,这些细节需要自己仔细对照指导书核实,不能完全依赖模型的理解。

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

第一单元:多项式求导

架构思维处于面向过程阶段。虽然用了Java,但本质上是把所有逻辑堆在几个类里,类与类之间的关系模糊,扩展性差。新增一个求导规则往往需要改动多处代码。

核心痛点:缺乏抽象,表达式、项、因子没有形成清晰的类层次,导致递归下降解析和求导逻辑耦合在一起。

第二单元:多线程电梯

架构思维进入并发场景下的职责划分阶段。开始意识到不同的类应该承担不同的角色:请求队列、调度器、电梯各自独立,通过共享对象通信。

核心收获:生产者-消费者模型锁的粒度控制。开始用接口和抽象类来定义协作协议,而不是直接依赖具体实现。

第三单元:JML规格化

架构思维转向契约式设计。JML强迫我在写方法之前先定义前置条件、后置条件和不变量,这与UML建模有相似之处——都是要求先想清楚"这个方法应该做什么",再考虑"怎么做"。

核心收获:理解了接口即契约,方法的可见性和副作用需要显式声明。这为第四单元的UML建模奠定了思维基础。

第四单元:UML建模

架构思维进入正向设计阶段。不再是先写代码再整理结构,而是先从业务需求中抽象实体和职责,用类图固化下来,再按图索骥地实现。

最重要的转变是:把"能跑通"和"设计合理"分开看待。一个所有逻辑都堆在 Main 里的程序也能通过功能测试,但它在设计上是失败的。第四单元的评测机制(语义完整性检查、核心类设计、关键词覆盖率)让"设计合理性"变得可量化、可评测(虽然这个评测的稳定性还有改进空间)。

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

第一单元:手动构造和评测机对拍样例

评测机主要靠大量数据“盲狙”尝试是否能hack,效率较低。手动构造测试以边界值为主:最高次项、零多项式、嵌套括号、负指数等,不过缺点是不够全面,主要靠"想到什么测什么"。

第二单元:并发测试的特殊性

多线程bug具有不可复现性,普通的手工测试价值有限。开始意识到需要压力测试(大量请求、极端时序)和日志分析。学会了用 Thread.sleep 和特定请求顺序来复现竞态条件。

第三单元:基于规格的测试

JML规格天然地给出了测试基准:前置条件决定输入范围,后置条件决定期望输出,不变量决定中间状态约束。测试思维从"猜边界"进化到从规格推测试用例,开始尝试等价类划分。

第四单元:交互式评测下的测试

本单元的评测机制是交互式的:还书、取书、续订等请求由评测机根据程序输出动态生成,这意味着程序的输出会影响后续输入。

这带来了新的测试挑战:不能只测单个请求的正确性,还要测请求序列的一致性。

测试思维的核心转变是从单点验证状态机路径覆盖:图书的每一条状态转移路径(对应状态图中的每条边)都应该被至少一个测试用例覆盖。

六、课程总结与收获

技术层面

四个单元在技术上的积累是递进的,每一单元都留下了具体的能力增量。

第一单元让我理解了递归下降解析和抽象语法树。把表达式、项、因子分别建模为类,让求导规则自然地映射到每个类的 derivative() 方法上,是我第一次体会到"用对象承载概念"的好处,也养成了用多态消除 instanceof 判断的习惯。

第二单元让我掌握了多线程编程的核心模式。在死锁和竞态条件的反复折磨下,我开始真正理解线程安全的本质:不是到处加锁,而是确定哪些状态需要被保护、保护多大范围。调度策略的抽象也让我第一次体会到策略模式的实际价值。

第三单元的JML规格训练改变了我写方法的习惯。在此之前写方法会直接想"怎么实现";JML之后,开始先想"前置条件是什么、后置条件是什么、会不会有副作用"。这种契约式思维与第四单元的UML建模形成了自然衔接——都要求先把"是什么"想清楚,再考虑"怎么做"。

第四单元让我实践了正向建模的完整流程:从需求中抽取实体、划分职责、用类图固化架构,再按图索骥地实现代码。两阶类图的机制让"设计先于编码"成为有截止时间、有评分约束的硬性要求,而不只是一句口号。

工程意识层面

课程结束后,我发现自己写代码时多了几个下意识的习惯:动手前先想职责边界,遇到新需求先问"它属于哪个类",写完功能后想"下次迭代改这里影响多大"。这些习惯在第一单元时几乎没有,是在一学期的训练下逐渐形成的。

同时,这门课也让我对大模型辅助编程有了更理性的认识。大模型能帮助梳理架构、追踪代码与模型的一致性,但对业务细节的理解往往不够准确,设计质量的最终保证还是对需求的深入理解和对代码的亲自验证。大模型能提升效率,但不能替代思考。

最后,OO完结撒花!

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

309

社区成员

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

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