OO Unit 4 & 课程总结博客

邓宇翔-24373294 2026-06-25 20:03:43

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

这一单元最明显的变化,是我第一次真正按照 “先建模、再编码” 的顺序把题目做完。hw13 开始时,我没有急着把所有逻辑写进代码,而是先把题目里的实体拆出来:LibraryManager 负责总调度,Book 负责书目和副本集合,BookCopy 负责状态、预约信息和移动轨迹,User 负责个人借阅 / 预约约束,BookshelfBorrowAndReturnOfficeAppointmentOffice 则分别对应三处实际存放图书的地方。这个阶段最有价值的地方,不是类画得多全,而是它逼着我回答 “某个信息到底该放在哪一层”。副本的状态不能散在各处,预约是否失效也不能塞进 User 里,整理流程更不能和借阅流程混成一团。把这些边界先画出来之后,代码就不再是到处补 if,而是沿着职责边界往下落。

到 hw14 和 hw15,正向建模的意义就更清楚了。需求一层层加进来之后,原来的骨架没有被推翻,而是继续长出了 ReadingRoomTreasuredBookshelfGradingOfficeBookCategoryLimit 这些更细的节点。这个时候二阶类图的作用就不只是“修补一阶图”,而是把实现过程中浮现出来的新职责重新安放回模型里:阅读行为由 ReadingRoom 单独托管,评分和珍藏判断由 GradingOfficeBook 共同承担,借阅 / 预约限制则从 User 中抽成 BookCategoryLimit。我会把二阶类图看成一面回看镜,一方面检查自己有没有把代码写偏,另一方面提醒自己哪些只是实现手段,不能反过来污染模型。对我来说,它真正的价值不是让图变得好看,而是让设计在写完代码之后仍然保持可追踪、可复核。


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

这一单元三次作业的架构骨架其实一直很稳定,只是每一轮往里加的职责不同。hw13 的结构最像一个标准的门面模式:InputManager 只负责读入和分发,真正的业务都交给 LibraryManagerLibraryManager 再把借书、还书、预约、取书、查询和开闭馆整理分给 BookBookCopyUser 和几个地点类。这里我刻意让“数据实体”和“场所容器”分开,Book 只管 ISBN 和副本集合,BookCopy 只管状态和轨迹,User 只管个人限制,这样 open / close 的整理流程才能围绕副本状态统一处理,而不会在各处散落副作用。换句话说,hw13 的架构目标不是炫技,而是先把最容易缠成一团的业务边界拆开。

hw14 的变化主要来自阅读、评分和珍藏书架。为了避免 LibraryManager 继续膨胀,我把 ReadingRoomTreasuredBookshelfGradingOffice 单独拆出来,让每个类只维护自己那一块容器或记录;同时把 B / C 类图书的借阅和预约限制抽到 BookCategoryLimit 里,User 自己只保留预约、阅读和个人状态。这样一来,代码和 UML 的关系就很直白:图里多一个职责,代码里就多一个类,而不是让原有大类继续硬扛。到了 hw15,真正新增的是时间和信用这条线,BookCopy 需要记录借出人、到期日和逾期状态,User 需要维护信用值,LibraryManager 则补上 Renew、逾期扣分和到期整理逻辑。这里我最在意的就是 UML 和代码之间能不能保持同构:最后回头看,类名、主要属性和主流程方法基本都一一对应,代码里那些额外出现的私有辅助函数,也只是把图里的业务拆细以后得到的实现细节,没有把模型拖散。这样做的好处很现实,后面每次改需求时,我都知道应该回到哪一层去改,而不是在一团代码里盲摸。


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

整个 OO 课程我使用大模型的频率并不高,尤其是建模部分,U1 部分的建模是我完全独立完成的,U2 由于中间吃瘪了,因此 hw7 的建模过程我询问了 AI 的意见,但本质上也是我独立完成的(没有让 AI 参与建模),U3 则几乎不需要考虑建模,U4 的话 hw13 部分的建模是我独立完成的,然而 hw14 和 hw15 的迭代开发实际上就是在原有基础上加入一些进阶功能,基本上可以在原有骨架上完成,因此这两次作业我尝试用 AI 帮助我设计架构,我则负责反馈,效果还是很不错的。

我最初的想法是我对大项目的开发几乎是没有任何经验,因此架构设计这一环我必须尝试自己完成。然而也正是由于没有经验,我在架构设计的路上也是处处碰壁,经常构建出让自己写的生不如死的架构。时代在发展,或许大模型的辅助是确有必要的,本来学习就应该是一个试错到反馈在不断循环的过程,而大模型则是将反馈的环节加快了而已,但也从另外一种角度说明了试错是十分有必要的,OO 没有 best 的模型,只有在不断打磨中走向 better 的模型,或许这门课设计如此多硬核作业的目的就在于此。

至于使用大模型的心得体会,感觉他相对来说更像是一位老师,水平比我高太多了,因此如果我全权交给大模型,那么它的工作就成为了一个黑盒的,虽然能够完成作业但对我的水平没有任何帮助,因此我会更想把它当成导师,在自己工作的基础上获取它的一些意见,从而加快试错到反馈的这个闭环。


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

U1 的架构设计是层次化的,其通过表达式化简这一个很常见的应用场景,向我们展示了一个很经典但是很实用的分层化设计 —— 从对表达式的解析,到各个因子之间的运算,再到因子的 toString,将一个棘手的问题拆分为相对独立却也存在通信的各个子集。这个单元的 OO 相对而言很纯粹,纯粹的架构设计,纯粹的代码,以及纯粹的优化思路,每一个环节都需要经过很多次试错,从而打磨出更加优秀的架构。

U2 的架构是基于线程模型的架构设计,以生产者 - 消费者模型为基础,从多个电梯的运行这一典型的多线程运用场景,向我们展示了架构设计需要考虑的关键因素 —— 线程安全。这是最折磨的一个单元,因为线程的错误很多是不可复发的,但也是最有价值的一个单元,我虽然处处碰壁,但是能明显感觉,自己在设计中的一些小巧思,能够同时兼顾实现的简洁和线程安全,正向反馈很足。不过线程安全的话题似乎远没有结束,或许还会存在更加优秀的设计方式,谁知道呢。

U3 倒是没有太多需要设计的架构,主要需要考虑的是对规格的严格复现,以及如何优化数据结构。规格化设计给出了所有需要实现的接口,虽然说整体框架设计好了,但是数据结构的设计也不是小问题,各个规格之间存在的联系、数据结构的优化也都是需要严肃考虑的问题,很多时候一个简单的优化需要动辄百余行的补丁,过分的优化又很容易导致 bug,因此需要细致考量这些指标之间的平衡。面向规格并不是让架构设计更为简洁,而是对架构设计本身也进行了一个分层,但接口层和数据结构层的联系又成为一个新的亟待考量的问题。

U4 题目本身并没有太大特点,但是其在架构设计阶段就引入了 UML 图来辅助设计。实际上在前几次的作业架构设计中,我就已经有在草稿纸上进行这样的设计,各个类之间的关联,每个对象的状态转移和生命周期,每个流程在对象之间的串联,确实需要在这样前置的考量下,才能有一个清晰的写代码的思路。UML 图则是把这些环节都给格式化,提供一个固定的模板,让这种前置性的建模和考量实在地体现到代码中。

回顾整个流程下来,感觉建模的思路很像是从最初的层次化设计,到后来对各个环节进行更为细致的考量,从代码本身引发的线程安全问题,到代码实现层面的规格驱动开发,再到架构设计层面的 UML 图,层层抽象,让我们实际深切地体会到了 OO 开发的各个流程,并对这些过程进行细致的思考。


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

说来惭愧,我的代码很少进行测试,这也导致我的强测和互测成绩并不优秀,经常出现致命的小 bug。

U1 和 U2 的测试主要是自己构造的压力测试,然而实际上我在设计之初就已经考虑了很多最坏情况,代码实现过程中也进行了很多优化,因此这些压力测试实际上并不应该成为我测试的重点,我需要的反而是更为全面的、对于各种 corner case 的测试:例如 U1 hw2 某个地方由于重构写法导致指数无法判别 + 号、hw3 没有考虑 f{0}(x) 和 f{1}(x) 可以反过来,U2 中 hw6 的设计思路各种问题、hw7 某处的死锁等等。这些问题如果经过全面的测试 + 反馈,应该都可以在强测阶段前一并消除,但是我由于偷懒,或是对自己代码和 AI 审查的盲目自信,导致最后丢掉了这些分。深刻反思!

U3 由于规格的存在,我尝试让 AI 为我构建 Junit 测试,相对而言有一定效果,但是 AI 构建出的测试我也没有审查,强度太小了!导致一个没有开 Long 的地方直接让我强测几乎整个炸掉。测试本身也是需要不断审查的!

U4 可能由于延续了偷懒的习惯(导致我最后还是没有进行测试,虽然很幸运最后通过了各次强测,但还是略有惭愧。

或许是受 OO 课程的影响,后续在做一些项目时,对于已开发部分的代码我都会要求进行测试,严格保证开发路径的合理性。在目前 AI 还没有能力完美判断代码是否正确的情况下,测试则是最好的反馈。一定要多测试!!!


总结自己的课程收获

OO 课程终于是落幕了。

在开学的各种忙碌与匆匆中,我开启了这门传奇课程的学习。在此之前,对于 OO 的概念,我几乎从未有过分深入的了解,却经常见人谈起,甚至于坐地铁时的乘务员也能与我们聊上两句。这究竟是怎样的一个概念?此前我或许以为就是一些代码封装的形式,可以让代码更具有可读性和可维护性,但也是此前,我的需求仅限于在高压的算法竞赛上尝试于最短的时间内实现我需要的算法,这些设计上的哲学却几乎无从谈起。

还是依稀能回想起和导员谈话的两次,他兴奋地向我介绍 OO 这门课,但同时也略带警告地提示我不要小瞧了这门课。诚然,hw1 的作业确实是让我吃了一堑,相较于小儿科级别的 OOpre,这 hw1 简直可以秒杀,我还记得当时看着巨大长的题面无从下手的感觉,后来从实验课和训练中获得了一定启发之后,才开始着手代码的实现。起步依旧是十分困难的,第一次需要同时编写这么多文件,难免感觉生疏,不过我还是成功写出了第一版代码,难绷的是其一共只有四个类。当时觉得这很不 OO,但又不太清楚为什么,思来想去还是改成了多个类,对每种因子实现相关的类,不得不说代码更加简洁了,对这种设计上的体会也稍稍有了些感觉。

第二堑估计就是 hw2 了,当时我还记得发了一个 “第一次写代码写到生不如死” 的朋友圈。我清楚地记得我已经完完全全想好该要怎么实现了,但发现代码却像是越写越多,像一个无底洞一样。自此之后我才真正开始敬畏这门课程的作业。后来的 hw3 相对而言就还好,毕竟已经经历过一次大风大浪。

后来的 U2 更是当头一棒 —— U1 还可以吃写代码的老本,U2 这种多线程的概念我则是从来都没有见过。当时上网找了特别多的资料,沉浸式地观看了许久,而且正值清明假期我还出去完了,在海边的时候还想着多线程的事,虽然说当时觉得是一种浪漫,但现在回想起来真是有些造孽的(或许是心态有些变化了吧。

U2 由于时间安排问题,hw6 喜提 O 房,hw7 也是 8h 冲刺进的 C 房,当时痛下决心说再把 OO 拖到最后一天来做就是傻福(现在看来还是),但实际上修复 bug 的时候,比较令我欣喜的是写代码时的一些小巧思设计,可以很方便快捷地解决问题。也就是这一点让我重拾了信心。不过线程安全这一块我觉得我还有很长的路要走,毕竟花的时间思考的时间相对来说都太少了。

U3 U4 放在 U2 之后跟两尊大佛一样,除了 U4 StarUML 依托的 UI 设计,其它的基本上不成难题。U3 更是直接做爽了 —— 清晰的复杂度边界,明确的规格要求,固定的算法流程,这不是算法竞赛题吗?当时花了很多时间纠结最优解,把一个 O(n) 的操作优化为 O(log n) 需要巨大的功夫 —— 比如通过维护一个数据结构,来均摊修改和查询的复杂度,但是这样每次修改都需要对数据结构进行维护,这就需要从代码里大海捞针出涉及到该属性修改的所有代码,总之也是个苦差,但我的一些设计还是比较好的,基本上能够很顺利地完成这部分工作,虽然 hw11 由于不开 Long 见祖宗了(U4 的图书馆系统更是典中典,除了需要花点时间做 UML 图之外,整个架构设计基本上没啥难点,也就是这个单元我尝试了一下大模型辅(jie)助(guan)开发,比起古法编程而言确实省了好些力气,不过我也不会后悔做出前三个单元均古法编程的决定,毕竟花大量时间写代码然后自己手动调试还到处碰壁的苦吃起来虽然很难但也真的是很有价值的。

总的来说,OO 这个课还是比较符合胃口的,至少有让我能够疯狂古法编程了一把。虽然我并没有花很多心思(没有花时间打磨、没有尝试多种方案、没有测试),同时也对某些环节仍然觉得有些质疑(例如实验),但我还是对这个课程心怀感激 —— 感谢各位助教老师,感谢同学们的支持与分享。学 OO 的经历回忆起来或许也是一段小有喜悦的时光。自认为没有水平担任助教,那么此文便是最好的告别。

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

309

社区成员

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

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