2026 OO 课程技术博客总结

侯博渊-24373120 2026-06-19 16:42:36

2026 OO 课程技术博客总结:从表达式、并发、规格到模型驱动开发

一、第四单元正向建模与开发总结

第四单元的三次作业都围绕图书馆管理系统展开,需求从最初的借书、还书、预约、取书和查询,逐步扩展到阅读、归还、评分、精品书架、信用分、借阅期限和续订。相比前三个单元,这一单元最明显的变化是,代码不再只是对输入输出规则的直接翻译,而是需要先建立一个相对完整的业务模型,再让实现围绕模型展开。

所谓正向建模,我的理解是先从问题域中抽象出稳定概念,再用 UML 描述这些概念之间的关系,最后依据模型进行编码。以图书馆系统为例,题面中反复出现的核心名词包括用户、图书副本、ISBN、书架、借还处、预约处、阅览室、预约记录、移动轨迹、信用分等。这些名词并不都应该变成类,但它们提示了系统中真正需要维护的状态和关系。比如“图书副本”需要记录当前位置和移动轨迹,“用户”需要记录借阅图书、预约状态、阅读状态和信用分,“预约记录”需要记录等待、送达、取走、失效等生命周期。

两阶类图在正向建模中起到了非常关键的作用。第一阶段类图更像是设计前的架构承诺,它要求我在写代码前先回答:系统由哪些核心类组成?每个类负责什么?类之间通过什么关系协作?这个过程可以避免一开始就把所有逻辑塞进 Main 或单个管理类中。第一阶段类图不一定完美,但它提供了一个初始框架,使后续编码有方向可循。

第二阶段类图则更像是对真实实现的校准。随着三次作业需求不断增加,第一阶段中没有暴露出来的细节会逐渐浮现。例如第十四次加入阅读、归还、评分、精品书架后,图书的位置状态明显不再只有书架、预约处、借还处和用户,还需要加入阅览室和精品书架。第十五次加入信用分、借阅期限和续订后,用户类中又需要维护信用分、应还日期、逾期扣分状态等信息。第二阶段类图要求我把这些变化重新纳入模型,而不是让代码和设计文档逐渐分离。

因此,两阶类图的价值不只是为了评测,而是帮助我完成从“预期设计”到“实现设计”的闭环。第一阶类图帮助我建立初始抽象,第二阶类图帮助我检查代码是否仍然保持清晰结构。两者之间的差异也反映了我对需求理解的变化。如果第二阶类图相比第一阶类图变化过大,往往说明第一阶段建模时没有抓住核心稳定概念;如果完全没有变化,也可能说明没有认真把实现中的新增职责反馈到模型中。

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

最终代码整体采用了以 LibrarySystem 为调度中心的架构。Main 负责读取官方包提供的命令,随后把命令交给 LibrarySystem 处理。LibrarySystem 根据命令类型分发到不同业务方法,例如借书、预约、还书、取书、阅读、归还、评分、续订和信用分查询。具体状态则分散在对应对象中维护。

BookCopy 表示一本具体副本,它是状态图中最核心的对象。图书可能从普通书架移动到用户,从精品书架移动到阅览室,从预约处移动到用户,也可能在整理流程中从借还处回到书架。所有这些变化都可以追踪到 BookCopy 中的移动方法和移动轨迹记录。状态图中的状态与代码中的位置枚举、移动方法基本对应,这使得查询移动轨迹时可以直接从对象历史记录生成输出。

User 负责维护用户相关状态,包括已经借阅的图书、预约列表、当前阅读的图书、信用分和借阅期限。第十五次作业中,用户对象的重要性明显上升,因为很多请求是否成功不只取决于图书是否存在,还取决于用户当前是否持有同类书、是否已有未完成预约、信用分是否满足权限、图书是否逾期等。

Reservation 则承载预约生命周期。预约不是一个简单的布尔值,而是有等待、送达、取走、失效等状态。这个对象的存在让预约逻辑更清晰,尤其是在处理预约送达后保留五天、过期后扣分、过期书籍重新整理等规则时,比只在用户类中放几个字段更容易维护。

BookshelfBorrowReturnOfficeAppointmentOffice 分别对应图书馆的不同部门。它们的职责比较单纯,主要是维护当前位置中的图书集合,以及提供查询、添加、删除等操作。这种设计让 LibrarySystem 可以专注于业务流程编排,而不是直接操作一堆散乱集合。

从 UML 模型到代码实现的追踪关系可以概括为:

模型元素代码对应追踪关系
类图中的用户类User维护借阅、预约、阅读、信用分
类图中的图书副本类BookCopy维护位置、状态变化、移动轨迹
类图中的预约类Reservation维护预约生命周期
类图中的部门类BookshelfBorrowReturnOfficeAppointmentOffice维护不同位置的图书
状态图中的状态迁移BookCopy 的移动方法对应图书位置变化
顺序图中的预约场景handleOrdermoveForReserve对应用户预约与整理送书
顺序图中的取书场景handlePick对应预约处到用户的转移

当然,最终代码和 UML 模型并不是完全一一对应的。比如 LibrarySystem 在代码中承担了较多调度职责,许多流程判断集中在这个类中;而 UML 模型中看起来职责可能更均匀。这说明实际编码时,为了控制复杂度和输出顺序,有些编排逻辑会自然集中到系统层。关键在于,这种集中不能破坏领域对象的核心职责。图书自己的移动轨迹仍由 BookCopy 维护,用户自己的信用分和持有状态仍由 User 维护,预约生命周期仍由 Reservation 维护,这样整体结构仍然可追踪。

这次修复 bug 的过程也体现了模型追踪的重要性。原本代码把“借书”和“取预约书”都复用了 canBorrow 判断,但题面中二者规则并不完全相同。借书需要信用分大于 80,而取已经送达的预约书只需要满足持有数量限制。这个问题本质上是模型中没有区分“借阅权限”和“持有合法性”。修复后增加了只检查持有数量限制的方法,使代码职责更接近题面模型。

三、大模型辅助正向建模的经验

在第四单元中使用大模型辅助建模,我最大的体会是:大模型很适合帮助整理复杂需求,但不能直接把它当成最终架构设计者。复杂题面中有大量相似但不相同的流程,例如借书、取书、阅读都会让图书离开书架或预约处,但它们的权限限制、移动路径和后续影响并不一样。如果提示不够精确,大模型很容易把这些流程合并过度,产生看似简洁但语义错误的设计。

比较有效的使用方式是先让大模型做需求抽取。比如要求它列出所有实体、所有状态、所有操作、所有权限限制、所有信用分变化规则。这样可以帮助我快速建立题面的全局图景。接着,再让它把“需求规则”映射到“类、字段、方法”,形成一张追踪表。比如“预约后不取扣 15 分”应该对应 Reservation 的失效判断和 User 的信用分更新;“阅读后不归还扣 10 分”应该对应闭馆流程;“精品书架”应该对应 BookInfo 的评分统计和开馆前整理。

在架构设计阶段,我觉得应该这样引导大模型:

  1. 先要求它不要写代码,只给出领域模型。
  2. 要求区分实体类、控制类、状态记录类和工具类。
  3. 要求列出每个类维护哪些不变量。
  4. 要求针对每个操作说明前置条件、状态变化和输出。
  5. 要求指出相似流程之间的差异,尤其是不能错误复用的判断。
  6. 编码后要求它按题面做 code review,而不是只检查语法。

大模型在复杂场景中的另一个价值是帮助构造边界用例。比如这次取书 bug,如果只跑官方样例不一定暴露,但构造“用户预约成功后信用分下降,然后再取书”的场景,就能发现复用 canBorrow 是错误的。大模型可以帮助提出这种跨日期、跨状态的测试思路。

但大模型也有局限。它可能会默认“复用越多越好”,或者忽略题面中非常细的时间点,例如“闭馆后立即扣分”“保留期第 5 天闭馆后失效”“开馆前整理后借还处不应有书”。因此,使用大模型时不能只问“怎么设计”,还要追问“哪些规则最容易被写错”“哪些状态变化发生在开馆前,哪些发生在闭馆后”“哪些判断只适用于某个流程”。我认为这才是复杂场景下比较可靠的人机协作方式。

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

第一单元是表达式解析和化简。最开始我的架构设计思维还比较朴素,主要是把输入解析、表达式结构、求导和化简拆成不同类。那时我更关注“如何把功能做出来”,比如 Lexer 负责分词,Parser 负责递归下降,表达式树负责计算和输出。这个阶段让我第一次体会到对象可以承载递归结构,而不是所有逻辑都写成字符串处理。

第二单元是电梯多线程。这个单元让我意识到,架构不仅是静态类划分,更重要的是对象之间的协作协议。调度器、电梯线程、请求队列之间如何通信,什么时候等待,什么时候唤醒,什么时候结束,都需要设计清楚。相比第一单元,第二单元的难点不再是单个函数是否正确,而是多个对象在时间维度上能否稳定协作。

第三单元是 JML 规格。这个单元让我开始从“实现视角”转向“契约视角”。JML 中的前置条件、后置条件、不变量和异常要求,让我意识到一个方法的意义不只是它内部怎么写,还包括调用前后必须满足什么语义。这个阶段的架构设计更关注数据结构和规格之间的一致性。例如选择什么容器,不只是性能问题,也会影响异常判断、关系维护和查询行为。

第四单元是 UML 正向建模。相比前三个单元,它更强调从问题域出发进行抽象。类图描述静态结构,状态图描述对象生命周期,顺序图描述对象交互流程。通过这一单元,我逐渐形成了更完整的设计思路:先找稳定概念,再找状态变化,再找对象协作,最后才是具体代码实现。

回顾四个单元,我的架构思维大致经历了这样的变化:第一单元关注“怎么拆功能”,第二单元关注“怎么协作”,第三单元关注“怎么满足规格”,第四单元关注“怎么先建模再实现”。这四个层次叠加起来,才比较接近真正的面向对象设计。

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

第一单元的测试主要是输入输出对拍。表达式作业适合随机生成表达式,再用不同实现或数学工具比较结果是否等价。我当时关注的是括号、符号、指数、嵌套、化简边界等问题。测试目标比较明确,就是表达式是否解析正确、输出是否等价。

第二单元进入多线程后,测试思维发生了明显变化。电梯程序的输出可能不唯一,因此不能只比较固定答案,而要检查输出是否合法。更重要的是,并发程序可能出现死锁、线程提前结束、请求丢失、等待时间异常等问题。这个单元让我意识到,测试不仅要验证结果,也要验证过程是否满足约束。

第三单元的测试围绕 JML 规格展开。由于规格非常明确,测试可以更有针对性地检查每个方法的前置条件、后置条件和异常行为。我会更关注边界数据、重复元素、不存在元素、异常计数、关系一致性等。这个阶段的测试更像是在验证契约,而不是简单跑样例。

第四单元的测试最强调状态机和历史轨迹。图书馆系统中,当前命令是否成功往往取决于之前很多天发生过什么。比如用户是否已经有未完成预约,图书是否已经送到预约处,预约是否过期,用户信用分是否下降,图书是否在普通书架还是精品书架。测试必须构造连续场景,而不能只看单条命令。

我在第四单元逐渐形成了几类测试思路:

测试类型典型场景
单流程测试借书、还书、预约、取书、阅读、归还
跨日期测试预约保留期、借阅期限、续订后归还
信用分测试按时还书加分、逾期扣分、阅读未还扣分、预约未取扣分
状态迁移测试查询图书从书架到用户、借还处、预约处、阅览室的轨迹
权限边界测试信用分为 0、40、80 时不同操作是否允许
整理流程测试开馆前和闭馆后移动是否符合约束

这说明测试思维也从“样例驱动”逐渐变成“规格驱动”和“状态驱动”。越复杂的系统,越需要围绕状态转移和不变量设计测试。

六、课程收获

OO 课程最大的收获,是让我逐渐理解“面向对象”不是简单地多写几个类,而是用对象承载稳定概念,用状态表达业务规则,用协作完成复杂流程。一个类是否合理,不取决于它名字是否好看,而取决于它是否维护了清晰的职责和不变量。

第一单元让我理解了递归结构和抽象语法树,第二单元让我理解了并发协作和调度,第三单元让我理解了规格和契约,第四单元让我理解了模型和实现之间的追踪关系。四个单元合在一起,实际上构成了一条从代码能力到设计能力的训练路径。

这门课也让我更重视重构。很多时候,第一次写出来的代码并不是最合理的。随着需求增加,如果不及时调整结构,就会出现大量重复判断和隐藏 bug。比如图书馆作业中,如果不区分借书权限和取书后的持有合法性,就会因为错误复用导致强测失败。重构不是为了让代码显得复杂,而是为了让概念更准确。

另一个重要收获是测试意识。以前我可能认为通过样例就差不多了,但 OO 作业让我认识到样例只能说明最基本情况。真正容易出错的是边界状态、跨天状态、异常状态和多个规则叠加的场景。好的测试应该尽量覆盖状态变化路径,而不是只覆盖输入格式。

最后,UML 建模让我意识到,设计文档如果只是代码写完后的形式化补充,价值会很低;但如果它能参与编码前的思考,并在编码后反过来校准实现,就能真正帮助理解系统。第四单元虽然工作量不小,但它让我更清楚地看到:复杂系统需要模型,模型需要实现验证,实现又需要测试反馈。三者结合起来,才是比较完整的软件开发过程。

...全文
75 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
串联谐振双有源桥(SR-DAB)DC-DC变换器闭环仿真研究内容概要:本文围绕串联谐振双有源桥(SR-DAB)DC-DC变换器的闭环仿真展开研究,重点探讨其在电力电子系统中的动态响应特性与控制策略。通过对SR-DAB变换器建立数学模型,并结合Matlab/Simulink进行闭环仿真,分析系统在不同工作条件下的电压、电流波形及功率传输效率,验证控制算法的有效性与稳定性。研究涵盖系统建模、控制器设计(如PI控制)、软开关实现条件、抗干扰能力以及动态调节性能,旨在提升变换器在新能源、储能、数据中心供电等场景中的可靠性和能效水平。; 适合人群:具备电力电子、自动控制理论基础,从事新能源、微电网、电力系统仿真等相关领域的科研人员与工程技术人员。; 使用场景及目标:①用于高校及科研机构开展DC-DC变换器控制策略的教学与实验;②为工业界在高效率隔离型功率变换系统的设计与优化提供仿真依据和技术支撑;③服务于数据中心、电动汽车、可再生能源并网等场景下的电源系统研发。; 阅读建议:建议读者结合Matlab代码实践仿真流程,重点关注系统建模与控制器参数整定部分,通过调整负载、输入电压等条件观察系统响应,深入理解闭环控制对变换器性能的影响机制。
内容概要:本文介绍了FastReport VCL/FMX/LCL 2026.2.4版本的更新内容,重点涵盖核心引擎、图形处理、用户界面及导出功能的优化与修复。主要更新包括修复了Developer Express兼容性问题、TfrxSVGGraphic在TImage中的显示问题、PDF/A导出合规性、EMF图像旋转异常,以及ReportTree拖拽功能等问题。同时,部分模块新增了HTMLTags对XLSX导出的支持、内置右键菜单和新图标,并改进了FastCube组件的元素调整体验。此外,还修复了CPP脚本中Result参数名的Bug以及自定义过滤器中OR操作失效的问题。; 适合人群:使用Delphi或Lazarus进行开发,且涉及报表设计与数据展示功能的中高级开发者;尤其适用于需要集成FastReport控件到企业级应用中的技术人员。; 使用场景及目标:①提升报表系统在不同平台(VCL/FMX/LCL)下的稳定性和兼容性;②满足PDF/A标准的文档归档需求;③优化用户交互体验,如拖拽操作与元素缩放;④增强脚本支持与数据集字段识别能力,确保开发效率与功能完整性。; 阅读建议:建议结合官方更新链接和实际项目中使用的FastReport模块对照查看,重点关注自身所用组件(如VCL、FMX或Lazarus版)的具体修复项,及时升级以规避已知问题并利用新特性优化报表功能。

309

社区成员

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

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