309
社区成员
发帖
与我相关
我的任务
分享在面向对象第四单元中,我经历了一场从先写代码到模型驱动的思维转变。按以往的习惯都是是拿到需求直接敲代码,最后为了应付检查才补画 UML 图,而本单元要求实践的正向建模与开发完全相反。需要我们先从需求出发,绘制出完整的 UML 模型,确认系统架构无误后,再将模型转化为代码实现。
在这个正向建模的过程中,两阶类图起到了承上启下的指导作用。概念类图主要聚焦于问题空间,它的主要任务是识别现实世界中的核心实体、关键属性以及它们之间的高层结构关系,而不关心具体的编程语言特性和实现细节。在本单元的图书管理系统设计中,概念类图帮我快速梳理出系统包含的核心概念,比如书籍、副本、用户、书架、预约处和借还处等。这一阶段能够不受存储数据结构的干扰,专注于理清图书馆业务的底层逻辑和实体边界,确立系统的核心词汇表。实现类图则转向解空间。它是在概念类图的基础上,结合面向对象语言的工程实践进行精细化调整的产物。在这一阶段需要明确标注出类、方法的可见性修饰符、具体的参数类型和返回值、精确的关联与组合依赖关系,以及设计中引入的特殊机制。
整体架构如下:
核心控制层:LibraryManager 作为整个系统的中央控制器,负责接收外部指令、管理系统当前的日期以及统筹协调各个服务部门。
领域实体层:
Book:维护书籍的全局属性,并在后续作业中动态维护评分信息以判断是否属于“珍本书”。
BookCopy:代表某本书的具体物理副本,包含唯一的 copyId,并维护其全生命周期的移动轨迹。
User:封装了用户的个人状态与借阅限制,包括对 B 类书持有量限制、C 类书重复借阅限制 以及在阅读室的在读状态等。
服务部门层(状态持有者):
Bookshelf 与 TreasuredBookshelf:分别作为普通书架与珍本书架,用于存放库存书籍,并支持按 ISBN 检索和提取。
BorrowAndReturnOffice:暂存用户归还的书籍,等待每日清零和重新整理。
AppointmentOffice:管理用户的预约请求,内部使用 reservedBooks 和 expireDates 映射来精确处理预约过期逻辑。
ReadingRoom:作为阅览室,管理在馆阅读的图书副本。
在将 UML 模型落地为实际 Java 代码的过程中,两者的追踪关系主要体现在静态结构的一致性与动态行为的微调上:静态结构方面,代码严格遵循了模型中定义的类名、方法名和可见性。例如,AppointmentOffice 类中的 acceptOrder 和 pickBook 函数,精确追踪了类图和顺序图中定义的 order 与 pick 操作,各部门内部的方法调用链路也完全符合顺序图定义的生命周期边界,未出现非法的交叉调用。然而,由于静态模型难以直接表达底层的工程性能考量,代码在落地时进行了结构转化。模型中简单的“1对多”关联线,在具体代码中被实现为更具针对性的复合型容器——如 AppointmentOffice 内部使用 userId + "_" + isbn 作为拼接键的 Map<String, BookCopy> reservedBooks,以此在追踪模型职责的前提下,将检索的时间复杂度优化至 O(1)O(1)。此外,针对图书评分波动引起的“珍本书”属性突变等动态约束,在代码中通过编写辅助校验函数来辅助状态机迁移,对静态 UML 无法全盘承载的运行时状态进行了必要的细化补充。
本单元尝试引入大模型辅助进行架构搭建,但在面对长篇幅、多业务分支的图书管理需求时,如果直接输入全部文本,大模型给出的代码往往存在职责不清、类关系冗余等设计缺陷。为了让大模型在复杂业务场景下输出高质量的架构,实践中主要采用了递进式交互和强约束的引导方式。
首先是划分设计层次,避免一步到位。交互时先要求大模型仅输出领域内的核心实体、值对象与聚合根的职责边界,不编写具体方法;在确认其梳理的业务概念无误后,再引导其细化类图的方法签名和类间依赖,期间人工接入干预其冗余的类间耦合。针对状态流转复杂的场景,单独向其输入状态迁移规则,使其专注于生成状态模式框架或流转伪代码。
其次是显式强调极端边界约束。在编写每日闭馆整理等高密度流转逻辑前,将特殊限制作为前置校验条件明确写在 Prompt 中,要求其先编写检查逻辑的伪代码。
最后利用编译器和用例的反馈结果进行闭环微调。将 Checkstyle 的报错、UML 工具的校验异常或 JUnit 失败日志直接反馈给大模型,使其在精准的错误上下文中进行局部代码重构与规范对齐。
第一单元:改变过程思维
这个单元是我痛苦破除“面向过程思维”的阶段。刚开始面对复杂的表达式,本能地想用一个巨大的面向过程函数去切分字符串。在迭代中,我逐渐理解了组合模式的魅力,学会了将表达式拆解为 Expr、Term、Factor 等多层嵌套的对象,构建出语法树。这一阶段,我的架构思维停留在封装、继承、多态等基本概念的运用上。
第二单元:并发架构设计
进入多线程领域,架构设计的核心变成了“如何优雅地处理多线程并发协作与线程安全”。我深刻体会到了生产者-消费者模式、策略模式以及观察者模式在复杂并发场景下的精妙。我不再只盯着单一对象的属性,而是开始构筑线程安全的共享资源,并合理隔离输入线程、调度器线程和电梯执行线程。架构思维跃升到了高并发控制、交互契约与解耦设计。
第三单元:规格驱动设计
本单元让我认识到:好的架构不仅要有清晰的结构,更要具备严密的规格约束。通过遵从 JML 规格,我学会了在严格满足前置/后置条件和不变量的前提下进行架构开发。同时,我也明白了“规格不等于实现”——在满足 JML 的逻辑正确性的同时,必须在架构底层引入高效的算法和中间状态维护,实现了逻辑严密性与工程性能的平衡。
第四单元:模型驱动设计
到了第四单元,我的架构思维最终走向了模型驱动架构。通过类图进行静态建模,通过顺序图和状态图进行动态交互建模。至此,我能够站在系统全生命周期的顶层视角,自顶向下地规划一个复杂系统的演进,真正理解了低耦合、高内聚在大型软件工程中的实际落地方式。
与架构思维同步演进的是系统测试方法的演变,我的测试策略逐步从盲目的用例构造过渡到了体系化的质量保障:
第一单元的测试处于初级阶段,主要依靠手工构造大数、零指数、多重嵌套括号等边界用例,辅以简单的 Python 随机测试脚本,测试本质上是黑盒且零散的。第二单元由于多线程的引入,测试空间增加了时间和状态两个维度。传统的静态数据无法有效捕捉并发错误,为此我搭建了带有时间戳的模拟输入评测机,通过深入追踪电梯的并发状态,将测试重心转移到死锁、忙等及偶发性线程安全漏洞的检测上,掌握了动态打桩与日志分析方法。
第三单元接触 JML 后,测试思维转向契约验证与白盒覆盖。我开始深度依赖 JUnit 框架,不再寄希望于全局黑盒测试,而是严格对照 JML 规格中的 public normal_behavior 和 exceptional_behavior,针对每个核心方法的分支编写断言,以代码覆盖率和路径覆盖率为导向进行精准测试。第四单元的系统更加复杂,测试思维上升到了模型一致性校验和系统级不变量的回归测试。不仅要验证业务结果,更要核对 UML 关系与底层代码的匹配度。面对图书管理系统的多次功能扩张,通过建立分阶段的回归测试集,在确保系统底层不变量不被破坏的前提下验证了状态机的健壮性,真正建立了工程化的质量保障意识。
三个月的面向对象课程不仅带来了高强度的编码训练,更重要的是建立了成熟的软件工程思维,核心收获可以概括为以下三个方面:
一是具备了处理复杂业务的工程实现能力。在密集的项目迭代中,编写了数千行结构清晰的 Java 代码,掌握了泛型、集合容器、多线程并发组件、自定义注解及反射等核心语言特性的应用。对 Checkstyle 的严格执行,也让我养成了良好的代码规范习惯。
二是确立了设计模式与系统架构的落地自信。设计原则和常用设计模式不再停留在理论层面,而是成为了应对复杂业务演进、解决底层解耦问题的实用工具。在面对不断变动的业务需求时,能够更有预见性地规划模块边界。
三是内化了系统化的工程方法论。第三单元的规格契约精神与第四单元的正向模型驱动,让我真正体会到了软件开发中“规范先行”的价值。在面对大型或者高密度的功能迭代时,不再盲目敲击代码,而是能够保持冷静,通过领域拆解、契约限定、分层重构来降低系统复杂度,这一方法论将持续指导我后续的计算机系统设计与开发工作。