OO第四单元博客作业

肖轲-24371263 2026-06-25 21:49:01

1. 正向建模与开发总结

本单元的作业形式与先前的三个单元都不太一样,以前都是简单的构思后直接开始代码实现,而本单元则是需要先建模再完成代码实现。在本单元的建议图书馆系统的任务中,两阶类图发挥了“先稳定结构、后沉淀实现”的关键作用。

一阶类图:确立“协调者+场所+实体”的职责边界

编码前,最容易犯的错误是把所有借书、预约、整理、扣分逻辑都堆在一个大类里。一阶类图的核心价值就是提前划定三类对象的职责:

  • 实体对象BookCopy 管理副本状态和移动轨迹,User 管理信用分与借阅列表,Reservation 管理预约生命周期。
  • 场所对象BookShelf(内部区分普通/精品)、BorrowReturnOfficeAppointmentOfficeReadingRoom 各自负责自己范围内的图书存取。
  • 总控对象LibraryManager 仅作协调,接收指令并委托给场所或实体方法,不亲自执行具体操作。

这种设计承诺,让后续信用分、借阅期限、精品书架整理等需求到来时,可以很自然地将新规则放入现有类中:信用分判断加入 User,借阅期限加入 BookCopy,整理逻辑集中在 LibraryManager.move() 里。整个架构骨架没有被动摇。

二阶类图:编码后对齐实现细节

一阶类图无法预见所有实现细节。代码完成后,二阶类图补充了实际演化出的具体方法和关系,例如在第三次的迭代中:

  • User 中增加了 canRead 来根据credit判断阅读权限,增加了 addCredit 来管理信用分变化。
  • BookCopy 中增加了 borrowExpirysetDueDaterenewisOverdue,封装了借阅期限和逾期扣分状态。
  • LibraryManager 中加入了 punishOverdue,专门在闭馆时处理逾期扣分,并用 borrowedBookCopies 映射追踪在借图书。

这些补充让二阶类图不仅能描述“系统如何组织”,还能解释“为什么某个方法放在这个类里”。一阶定方向,二阶对实现,二者共同保证了模型与代码的一致性。

2. 架构设计总结

我的最终架构可以划分为三层:总控层LibraryManager)、场所层BookShelfBorrowReturnOfficeAppointmentOfficeReadingRoom)、实体层BookCopyUserReservationGradeOffice)。模型与代码的追踪关系如下。

2.1 类图 → 代码:结构可追踪

img

类图设计代码实现追踪说明
LibraryManager 持有各场所和实体集合LibraryManager 拥有 bookShelfborrowReturnOfficeappointmentOfficereadingRoomusersreservationsprivate final 字段总控层对场所和实体的组合关系直接在代码中体现
UserReservation 一对一关联User 类中 private Reservation activeReservation用于快速判断用户是否有未取预约
BookCopy 聚合移动轨迹BookCopy 内部维护 List<LibraryTrace> movingTraceListmoveTo 方法追加轨迹状态图中每次转移都会调用 moveTo,自动记录历史
BookShelf 内部区分普通与精品书架BookShelf 类中 normalShelftreasuredShelf 两个 MapaddBookCopy 则根据 score 选择容器评分为 4 以上进入精品书架的逻辑集中在此

2.2 状态图 → 代码:行为可追踪

img

状态图定义了 BookCopy 在书架、预约处、借还处、阅览室和用户之间的全部合法转移。每个转移的守卫条件和触发方法都能在代码中找到对应。

状态图转移代码实现追踪说明
BOOKSHELF → USERBookShelf.borrowBook() 中先调用 user.checkBorrowLimit(isbn),通过则 copy.moveTo(USER, date)canBorrow 在代码中体现为信用分与持有数量的双重检查
APPOINTMENT_OFFICE → USERAppointmentOffice.pickBook() 中检查 !copy.isOverdue(date, true)逾期副本不可取,与状态图一致
BORROW_RETURN_OFFICE → BOOKSHELF (整理)LibraryManager.move() 中遍历 borrowReturnOffice.getBookCopies(),根据评分调用 copy.moveTo(state, date)整理时借还处清空,移至正确书架,触发方法对应 clearBro()
BOOKSHELF → TREASURED_BOOKSHELF (重排)BookShelf.move() 中检查 gradeOffice.isTreasuredBook(isbn),若符合则 copy.moveTo(TREASURED_BOOKSHELF, date)开馆前重排书架时,评分达标的副本被迁移到精品书架

(在这里建议一下,如果可以的,希望下一年的OO这个状态图的Gaurd可以不强求是一个成员变量,毕竟并非每个条件判断都会设一个专门的变量,如果可以放方法的话那再好不过)

2.3 顺序图 → 代码:交互可追踪

顺序图描绘的预约和取书场景,在我的实现中是由 LibraryManager 串联起 UserAppointmentOfficeReservationBookCopy 等对象完成的。整个过程清晰地分为预约阶段和取书阶段,中间的整理流程由LibraryManager.move()来衔接的。

预约阶段:用户发起预约后,LibraryManager 先调用 User.checkBorrowLimitUser.hasReservation 完成资格检查,随后委托 AppointmentOffice.orderBook 创建一个状态为 PENDINGReservation,并将其绑定到 User.activeReservation。此时预约记录已生成,但预约处尚无实体书。

取书阶段:整理流程在开馆或闭馆时将副本从书架送至预约处,并将 Reservation 状态转为 RESERVED。当用户发起取书时,LibraryManager 调用 AppointmentOffice.pickBook,该方法内部再次确认预约有效且未逾期,随后执行 BookCopy.moveTo(USER) 完成副本转移,并调用 Reservation.fulfill() 标记预约完成。整个过程在一条消息链中完成,取书成功后预约即从系统中清除。

顺序图消息代码中的方法追踪说明
LibraryManagerUser: checkBorrowLimitUser.checkBorrowLimit(isbn)验证信用分与持有数量限制
LibraryManagerAppointmentOffice: orderBookAppointmentOffice.orderBook()创建 PENDING 状态的 Reservation
LibraryManagerAppointmentOffice: pickBookAppointmentOffice.pickBook()查找预留副本,验证未过期,执行移动
AppointmentOfficeBookCopy: moveTo(USER)BookCopy.moveTo(LibraryBookState.USER, date)副本从预约处转移至用户,记录轨迹
AppointmentOfficeReservation: fulfillReservation.fulfill()标记预约为已完成
AppointmentOfficeUser: addBookCopyUser.addBookCopy(copy)副本加入用户借阅列表

(orderNewBook与getOrderedBook在表中就不列出了)

3. 如何引导大模型在复杂场景中完成架构设计任务

在本单元包括前几个单元的训练中,我逐渐意识到大模型的力量是十分有限的,它可以高效完成一些不复杂的任务,而在复杂的场景中它几乎不太可能正确地一次性独立完成,所以如果希望大模型在复杂场景中完成架构设计任务,核心就是拆分任务,明确请求并且及时反馈/修正潜在的问题。

  1. 渐进式需求输入,分阶段收敛设计
    将复杂系统拆解为基础骨架、功能增量、规则强化三个迭代,每次只让大模型关注增量变化,避免一次性输入导致设计泛化。例如先建立借还预约核心,再增加精品书架和信用分,使架构逐步演进。

  2. 明确架构风格与职责边界
    提前约束大模型采用“协调者+场所容器”模式,并要求它不断审视类的职责是否单一。例如,当大模型提议将Reservation放入AppointmentOffice时,通过直接反馈“全局状态应由总控管理”的原则,使模型自行修正保持内聚。

  3. 要求输出形式化模型并紧盯约束
    让大模型直接生成类图、状态图(我个人就是让它生成PlantUML的图,毕竟方便排查,且易于直接通过大模型生成),并对Guard长度、Trigger命名等评测规则做出约束。通过可视化反馈快速发现缺失的关联、错误的状态转移。

  4. 交互式纠错与设计审查
    利用大模型检查代码与模型的一致性。例如当move()顺序可能导致二次移动时,通过提问“如何保证每本书仅移动一次”引导大模型给出重排步骤,再将其融入设计。对逾期扣分等逻辑缺陷,通过具体反例促使模型修正。

大模型不会为你的代码负责,它到底只是工具,只有人才可以决定自己架构的走向。对大模型有效的引导不是让大模型替代设计,而是通过分步约束、形式化表达和持续比对,将大模型的发散能力收敛到严谨的架构轨道上。

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

  1. 第一单元:表达式解析和化简
    我的架构最开始极为的简洁,核心的对象只有Expr以及Poly,其中Poly则用一个Map管理多项式指数与系数。但是在第二次迭代指数函数的加入,我的架构就完全无法扩展,只得重构新增Mono类,于是架构就变成了一个Expr包括多个Poly,而一个Poly包括多个Mono,这样分层设计,使得第三次的迭代我只需要改变对应的部分就行,比如新增指数函数,就在Mono部分迭代就好而不必变化其他的部分。这也是让我第一次体会到,层次化的架构可以极大的保证架构的可拓展性。

  2. 第二单元:多线程电梯
    本单元的核心是并发编程,主要是要保证线程间的互斥与协作。本单元三次作业中,我的架构设计思维经历了从“功能实现”到“分层解耦”,再到“状态驱动”的转变。第一次作业,我采用“电梯即线程”的单层模型,输入、调度、执行全部耦合在一个线程里,同步用粗粒度 synchronized,空闲用 sleep 轮询。这种设计仅能应付简单需求,扩展性极差。第二次作业引入独立的调度器线程,将“分配”与“运行”解耦;电梯内部引入状态机管理正常、检修等生命周期;同步则升级为 ReentrantLock + Condition,用等待/通知替代轮询。在这次作业的折磨磨练我意识到线程之间应该通过共享队列协作,而不是轮询检查。第三次作业彻底改变了我的认识——一个井道内有两个轿厢,共享物理空间和状态。我将 Elevator 进一步抽象为井道管理器,负责状态同步和 F2 互斥锁,两个 Cabin 线程只负责执行动作。同步设计走向精细化:不同资源使用不同锁,原子标志用 AtomicBoolean之类的保证,复合操作用 ReentrantLock 保护。本单元让我知晓,面对多线程编程时,关键就是辨析出互斥/协同的对象并统一进行管理。

  3. 第三单元:JML规格
    与前两个单元相比,第三单元的需求已经以形式化规格给出,架构思维变成“从契约到状态”,任务变成了如何优雅的“翻译”规格。在理解JML规格约束的基础上,决定哪些查询需要缓存。例如互关数量、视频的influence等,如果完全翻译规格,时间复杂度会教你做人;如果盲目缓存,有极有可能使得新功能的迭代变得困难,比如在第二次作业中我为了缓存heat导致下一次的迭代被冗杂的方法搞得不得不重写。从中我知道了效率与可拓展性需要一定的平衡。

  4. 第四单元:UML正向建模
    第四单元则把设计进一步前移到 UML建模。它的核心变成了如何正向建模架构。类图要求我确定对象之间的关系,状态图要求我明晰对象是如何变迁的,顺序图则要求我说明场景中对象是如何协作的。虽然过程略有难受,从这个单元我也知道的就是在开始代码实现前,一份全面的草稿十分重要。

5. 四个单元中测试思维的演进

在测试方面,我就主要是通过调试来一步一步的定位错误。首先根据题目构造一些基本的边界数据,然后进行测试;之后就尝试构造大量的数据进行广度的测试,如果发现错误,那么就进行减法——删除测试数据直到刚好错误不再发生,如此来定位发生错误的位置,这个方法在第四单元非常好用,除去第三单元我都是这么完成的,虽然笨但是有效。对于第三单元则比较简单,由于给出了JML规格约束,严格按照约束编写测试代码检查方法的行为是否符合JML即可。

6. 课程收获

经过一个学期的艰苦奋斗,OO也是圆满结束了。最后实在没想到颁奖典礼居然还给了我一个进步奖。怎么说呢?心情很复杂——说难受吧,获了奖;说开兴吧,每次的强侧都一塌糊涂——但还是感谢老师以及学长们的认可。从第一单元的递归下降算法到第四单元的UML,经过四个单元的磨练,从最次的角度来说,每次的格式检查让我现在代码的格式非常工整,与我大一相比,算是巨大的进步。当然不知于此,OO 这门课最直接的收获自然是在四个单元中一直在磨练的工程能力。第一单元递归下降教会了我层次化设计;第二单元我第一次解接触了多线程的编程,让我对于并发编程有了一个初步的理解;第三单元的JML规格化设计则是通过给定的规格实现方法并编写测试;第四单元的UML正向建模让我完整经历了从建模、实现到迭代的完整过程,对于正向建模在工程中的应用我也有所了解。不得不说,每个单元都给了我很深的印象,也培养了我在一些设计上的思想,比如层次化设计,抽象对象之类的。这些思想为我面对后续的软件工程乃至以后的学习都会有所帮助。OO这门课承载了无数的泪与汗水,现在是时候向他告别!

...全文
331 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复
打开链接下载源码: https://pan.quark.cn/s/589796089f72 C++课程设计任务列表,涵盖以下内容:1、识别并显示10至99范围内,各位数乘积超过各位数和的数值,例如数字12不满足条件,因为1乘以2小于1加2,故不输出;而数字27满足条件,因为2乘以7大于2加7,因此需要输出该数。2、开发一个功能,用于从用户输入的任意数量实数中找出最大值与最小值:首先要求用户输入一个正整数n,代表数值的个数,随后用户可输入任意n个实数,程序需找出这n个数中的最大值和最小值并将它们展示出来。3、实现两个已排序数组的合并操作:设有数组A和B,且假设这两个数组的元素均已按照降序排列。编写程序将A和B合并成一个新的数组C,并确保C中的元素同样保持降序排列。int A[10]={123, 86,80, 49,33,15,7,0,-1,-3};int B[10]={100,64,51,50,27,19,15,12,5,2};4、设计一个函数,用于计算特定分数序列前n项的总和,该序列为1/2,1/3,1/4,1/5,1/6,1/7,...。要求在主程序中提示用户输入一个整数n,并验证输入的合法性(n需大于1方为有效),若输入合法,则调用求和函数并显示计算结果。5、编写一个程序,计算两个用户输入日期之间的天数差:用户需以year1,month1,day1和year2,month2,day2的格式输入两个日期,程序随后计算这两个日期之间的天数间隔,并将结果输出到屏幕上。要求编制具有如下原型的函数difs2Date:long GetDayDifference(int y1,int m1,int d1,int y2,int m2,int d2);并在主函数中调用此函数,将计...
代码下载地址: https://pan.quark.cn/s/ee8627e4e6d7 ABAP调试器是一种功能强大的工具,可用于在执行期间对ABAP代码进行检验。除了常规的核心功能(例如逐行运行代码以及检验变量、字段符号和引用的值)之外,它还提供了一些辅助性的特性,能够简化并压缩调试会话的时长。并非所有使用者都熟悉这些辅助特性。SAP ABAP调试器是处理和优化ABAP代码开发与维护工作的核心资源,它配备了多样的功能来协助开发人员在运行状态下进行检验和排除故障。此资源着重阐述了ABAP调试器的一些高级特性,涵盖了深入分析调用堆栈、系统级调试、更新会话调试以及提升调试效率的方法。 1. **深入分析调用堆栈**:除了常规的应用程序调试,开发人员有时需要对调用堆栈的内部层级进行深入调试,特别是在错误出现在异步执行的更新处理或系统级程序时。通过启用**系统级调试**,可以访问通常不公开的系统代码,但这也会导致调用堆栈的显著增加,因此需要审慎操作。 2. **系统级调试**:对于不含业务逻辑的系统级程序,开发人员通常无需进行调试。然而,在特定情形下,例如进行错误追踪时,可能需要进入系统代码。借助调试器的“系统调试启用/禁用”选项,可以赋予对系统程序的调试权限。 3. **更新会话调试**:在处理异步更新任务,例如持久化业务数据时,错误可能发生在更新任务内部。激活**更新会话调试**,在更新任务完成后,调试器将自动启动,展示执行路径。比如,在变更成本中心后,通过输入调试指令 "/h" 启动调试,保存后能够看到更新过程中的错误。 4. **分析调用堆栈**:在进行深入调试时,调用堆栈是至关重要的。通过分析调用堆栈,能够定位到引发问题的具体位置,如在VB_V2_NORMAL...
源码链接: https://pan.quark.cn/s/a4b39357ea24 小程序雷达 AI 驱动的小程序生态选型与风险评估工具,把微信小程序开发资源转化为可筛选、可评估、可对比的技术雷达。 线上地址 主站: Vercel: 适合谁 正在做微信小程序技术选型的产品、研发和架构团队。 需要判断 Taro、uni-app、原生小程序、组件库、云开发和 SDK 风险的团队。 需要把历史 awesome 列表转成可筛选、可对比、可验证技术雷达的维护者。 可以做什么 Radar:按推荐状态、风险等级、资源类型、分类和适用场景浏览小程序生态资源。 Quick Search:快速搜索资源并跳转常用页面。 Compare:对比 Taro、uni-app、原生小程序等核心方案。 Advisor:输入选型问题,获得推荐结论、适用/不适用条件、迁移成本、下一步和证据来源。 Doctor:粘贴小程序项目配置,识别框架依赖、过时方案和迁移风险。 Weekly:查看小程序生态周报和近期风险信号。 数据概览 当前数据集中包含 236 个小程序生态资源。 完整资源可在 Radar 页面和导出能力中查看。 核心样例 Taro ★30.6k+ - 使用 React 的方式开发小程序的框架,同时支持生成多端应用 uni-app ★36.1k+ - 使用 Vue 语法开发小程序、H5、App的统一框架 MPX ★2.1k+ - 增强型小程序框架,深度性能优化,支持跨小程序平台开发,完全兼容原生小程序组件 WePY ★21.7k+ - 支持组件化的小程序开发框架 vant-weapp ★12.3k+ - 高颜值、好用、易扩展的微信小程序 UI 库 tdesign-miniprogram ★1.3...

309

社区成员

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

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