面向对象设计与构造第四单元

陈诚-23374234 2026-06-19 22:14:38

面向对象设计与构造第四单元:UML

1. 本单元的正向建模与两阶类图

在本单元第一次作业(第十三次作业)时,一阶类图做得很仓促,只建构了主要的类框架,类内方法、成员都设置得很粗糙。不过我反而认为这样更符合正向建模的精神。在后续作业中,由于迭代开发时对于整体架构已较为熟悉,反而让一阶类图的设计过于详细,想必不是练习的本意。

在正向建模设计类的过程中,我深切地体会到了继承的作用。建模的过程不仅需要将各种概念抽象成对应的类,为了保持一个清晰简洁的架构,还需要学会提取类间关系,将那些功能和行为有部分相似性的类通过继承的方式进行抽象和复用。例如,本次图书馆作业中包含许多“地点”:借阅处、书架、甚至用户也可以算作抽象的“地点”;它们都属于一种图书的容器,且都会提供一些相似的功能,例如添加图书、移除图书、查询图书等。通过抽象这些相似的行为,我们可以让类的组织结构更加清晰,代码的复用性也更高。

个人理解,一阶类图是宏观上建构类的框架和层次结构,可以快速帮我们理解系统的整体架构;而二阶类图则是在实际实现代码前,进一步细化类的设计,明确类的成员变量、方法等细节,帮助我们在实际代码实现前进行更加细节的设计。

2. 最终架构与 UML 追踪关系

本单元的三次作业围绕图书馆系统迭代展开。我的总体架构是以 Library 作为总控类,负责接收外部请求、判断业务合法性,并调度各个地点之间的图书流转;BookCopy 则表示具体的图书副本,维护其编号、当前位置、借阅期限和流转轨迹。除此之外,Place 作为图书容器的抽象父类,向下派生出 BookshelfBorrowAndReturnOfficeAppointmentOfficeReadingRoomUser 等具体地点或持有者。

在这一架构中,各个类的职责边界比较明确。Bookshelf 负责普通书架和精品书架的存放与调整,BorrowAndReturnOffice 负责还书后的暂存与整理,AppointmentOffice 负责预约与取书,ReadingRoom 负责阅览室内的临时占用,User 维护用户持有图书和信用分状态。Library 并不直接保存所有业务细节,而是通过调用这些对象的方法完成状态变化。最终代码中的类关系与 UML 类图中的继承、关联关系基本保持一致。

相比一阶类图,最终实现中最大的变化在于对细节职责的进一步下沉。最初的设计更多只是画出“图书馆、用户、书架、借还处、预约处”等主要概念;而在代码实现和二阶类图中,我将“图书副本状态变化”“到期开馆闭馆整理”“信用分惩罚与奖励”“精品书架迁移”等逻辑逐步分散到对应类中。

在代码实现过程中,类图和代码是共同演化的,类图的构建会根据实际代码实现过程中的需求和细节进行调整和完善。类图和代码之间的追踪关系是双向的:类图指导代码实现,代码实现又反过来验证和调整类图设计。当然,UML 也不会面面俱到,部分辅助的设计细节可能不会完全体现在类图中,但核心的框架和类关系是保持一致的。

3. 大模型辅助正向建模的体验

在第十三次作业中,我相对较少地使用了大模型的帮助。主体的类层次框架都是人工设计的,不过在设计的过程中针对部分架构的设计,我会咨询大模型的意见,帮助我更好地实现抽象和复用。

在后两次作业的迭代开发中,我就更多地使用了大模型来直接介入我的设计和实现过程。在这类迭代开发的过程中,更需要明确的是迭代新增和修改的功能;引导大模型设计的过程中,我一般会拆解本次的迭代新增内容,一步一步地投喂给大模型,降低一次性过多信息带来的可能的误解和错误。在开发结束后,我也会借助大模型分析可能的实现错误,事实证明这种借助大模型的静态查错还是非常有效的,可以发现许多自己对于题目的理解偏差和实现上的细节问题。

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

回顾四个单元,我对架构设计的理解大致经历了从“能拆开”到“拆得合理”的过程。第一单元中,我主要是自然地按照表达式解析的层次划分模块,将语法树结构和多项式运算分离;这种设计已经有一定的面向对象意识,但很多地方仍然带有面向过程的痕迹,例如依靠类型判断处理不同因子。

第二单元的多线程电梯让我第一次真正意识到对象边界与职责边界的重要性。线程安全不是简单地加锁,而是需要先明确共享资源属于谁、由谁负责保护。第三单元的 JML 则进一步强化了“先规格、后实现”的意识,使我在写方法前会更关注前置条件、后置条件和副作用。到了第四单元,UML 正向建模要求我在写代码前先抽象出类和关系,这让我更加重视设计本身,而不仅是完成当前功能。

总体来看,我的架构设计思维从一开始的“按功能分文件”,逐渐转向了“按对象职责组织系统”。一个好的架构不只是类的数量多、层次复杂,而是能够让后续迭代时新增功能有明确的落点,不至于把所有逻辑都堆到一个总控类中。

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

测试方面,我一开始主要依赖随机数据和对拍。第一单元表达式任务比较适合构造随机输入,再与评测机或其他程序比较输出等价性,因此测试思路偏向“黑盒验证”和覆盖边界情况。第二单元进入多线程后,测试难度明显上升,很多问题无法稳定复现,我开始更多依赖日志、条件断点和状态输出定位问题。

第三单元的 JUnit 测试让我对测试有了更形式化的认识。相比只看最终输出,单元测试更强调对对象状态变化和异常行为的验证,这实际上要求我理解方法的完整规格。第四单元中,图书馆作业的业务状态较多,测试时更需要关注图书在不同地点间的流转是否合法、用户信用分和借阅状态是否一致。

因此,我对测试的理解也从“找出错误输出”,逐渐转变为“验证状态和约束是否始终成立”。尤其是在迭代开发中,测试不仅是提交前的查错工具,更是防止旧功能被新需求破坏的保障。

6. 课程收获

这门课最大的收获,是让我比较系统地体会到了面向对象设计在不同场景下的作用。第一单元让我认识到抽象数据结构和分层计算的重要性,第二单元让我理解了并发环境下对象职责和同步边界的意义,第三单元通过 JML 强化了规格意识,第四单元则把设计本身前置到 UML 建模阶段。

此外,我也逐渐认识到,面向对象并不是简单地“把函数放进类里”,而是通过封装、继承、多态等机制来管理复杂度。一个设计是否优秀,往往不是看第一次实现是否方便,而是看后续需求变化时是否还能保持清晰、稳定和可维护。

最后,大模型的使用也改变了我的开发方式。它可以帮助我快速实现局部逻辑、检查潜在错误、补充测试思路,但真正决定代码质量的仍然是开发者对需求、架构和边界条件的把握。经过这门课的训练,我对“如何设计一个能继续演进的程序”有了更加具体的理解。

站在历史的十字路口,我们必须思考大模型带来的冲击。在未来的业界究竟需要我们掌握什么样的能力,大模型的趋势又会如何发展,这些问题都需要我们主动地、持续地去思考和探索。从业界需求下降到高校的课程设置和人才能力培养,调整和适应的过程必然存在迟滞。在如今这样一个变革的时代,主动的思考、对技术趋势的敏感是十分必要的。

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

308

社区成员

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

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