1. 总结本单元所实践的正向建模与开发,重点分析两阶类图在正向建模过程中的作用
在本单元的图书馆模拟系统中,我转变了“边想边写”的开发习惯,完整实践了“需求分析 -> 概念建模 -> 设计建模 -> 代码实现”的正向建模开发流程。
- 第一阶
- 它是沟通需求与代码的桥梁。在阅读长篇幅的图书馆业务需求时,概念类图帮助我迅速剥离掉具体的实现细节,提取出核心的领域实体(如
Library, BookShelf, User, TiBook)。在这一步,我只关注实体之间“是什么”的关系(例如“图书馆包含书架”,“用户借阅书籍”),而不去考虑底层是用 HashMap 还是 ArrayList。它保证了我们对需求的理解在宏观方向上不会跑偏。
- 第二阶
- 它是指导具体编码的蓝图。在概念类图的基础上,设计类图引入了具体的属性(类型、可见性)、方法(参数、返回值)以及设计模式的使用。设计类图要求我们将业务逻辑细化为类的接口。例如,我需要在
Library 类中明确加入处理指令的方法 handleReq(LibraryReqCmd req),在 User 类中明确加入信用积分 credit 的增减逻辑。当设计类图完成后,类的骨架就已经定型,后续的编码仅仅是“按图索骥”的填空工作。
2. 总结本单元作业的架构设计,及代码与UML的追踪关系
本单元架构设计:
基于提交的代码,系统采用了典型的集中式控制与职责委托架构:
- 入口与顶层控制:
MainClass 负责接收输入并将其分发给 Library。 - 核心:
Library 作为图书馆的调度中心,维护着整个生命周期的核心资源(BookShelf,用户映射表 users,日志记录 logs)。它对外暴露各种操作接口(如 open, qcs, handleReq)。 - 业务逻辑实现:
BookShelf 封装了所有书籍存放、移动、状态流转(如图书架到珍本区)的核心逻辑。User 类负责维护单一用户的借阅状态、预约信息、信用积分。TiBook 类则专注于处理书籍的借阅时间限制与续借逻辑。
代码设计与 UML 模型设计的追踪关系:
- 类图追踪: 代码严格按照 UML 设计类图生成。例如,代码中
Library 持有 HashMap<String, User> users 对应的正是 UML 中 Library 到 User 的一对多聚合关系。 - 状态图追踪:UML 状态图中定义的状态机流转,在代码中通过
@Trigger 注解得到了完美追踪。例如,Library 类中的方法 @Trigger(from = "READING_ROOM", to = {"BOOKSHELF", "TREASURED_BOOKSHELF"}) 精准映射了 UML 状态机中书籍从阅览室归还至书架的 Transition 边,确保了代码状态跃迁与模型设计严格保持一致。 - 顺序图追踪:UML 顺序图规定了对象间的消息传递顺序。在代码中,这体现为方法调用的层级关系:例如收到闭馆指令时,
MainClass 调用 Library.close(),Library 进一步调用 BookShelf 的内部逻辑并触发数据记录,这一调用链与 UML 顺序图的 Lifeline 消息交互一一对应。
3. 使用大模型辅助正向建模的体验与引导策略
在本单元中,我尝试利用大模型辅助进行 UML 架构设计。大模型在概念提取和样板代码生成上效率极高,但在处理复杂的业务约束时容易出现疏漏。
引导大模型在复杂场景中完成架构设计任务的策略:
- 需要通过 Prompt 明确指出业务边界,例如:“用户 B 类书只能借 1 本,C 类书可以借多本且不可重复。请根据此规则设计 User 类的属性和校验方法”。
- 让大模型生成架构或状态流转后,要求大模型自己扮演测试者:“请用你设计的类图,模拟用户借书满额后再次借书的流程,检查是否能阻断违规操作”。通过这种方式能有效逼迫大模型修正其设计缺陷。
4. 四个单元架构设计思维的演进
- 第一单元(表达式解析):从面向过程到面向对象。 刚开始依然带有强烈的 C 语言思维,试图用几个大循环解决问题,导致诞生了难以维护的“上帝类”。后续逐渐学会了将“表达式、项、因子”抽象为对象,体会到了树形结构和层次化设计的优势。
- 第二单元(电梯调度系统):引入并发与解耦。架构思维从单线程扩展到多线程。我学会了使用经典的生产者-消费者模式和流水线模式,深刻理解了共享对象的锁机制,以及如何通过中间件(如请求队列)将不同线程(输入线程与电梯运行线程)解耦。
- 第三单元(社交网络 JML):契约式设计。** 这一单元的架构框架已被 JML 规格限定,我的思维转向了“面向接口编程”。重点在于如何在满足契约的前提下,设计高效的数据结构与算法(如并查集、最短路径)来支撑架构的性能。
- 第四单元(图书馆 UML):上帝视角的系统级设计。** 架构思维跃升至系统层面。不再是拿到题目直接敲代码,而是先画类图、状态图,先规定好类与类交互的“通讯协议”。体会到了“图纸”对于复杂工程的指导意义。
5. 四个单元测试思维的演进
- 第一单元:狂轰滥炸。 测试手段主要是编写 Python 脚本利用正则表达式生成海量随机数据进行对拍。这种方式能找出崩溃点,但对边界条件的覆盖极其看运气。
- 第二单元:并发测试与时序敏感。随机测试不再完全奏效,因为 bug 常常是概率性发生的(死锁、轮询)。测试思维转变为构造极端并发场景(如同一时间投入大量同层请求)。
- 第三单元:单元测试与边界值。*JML 的出现让测试有了“法律依据”。全面引入了 JUnit 框架,测试思维转变为白盒测试和单元覆盖率驱动。我学会了针对前置条件(
requires)构造正常、异常分支,针对后置条件(ensures)断言结果。 - 第四单元:模型驱动测试。测试思维上升到业务逻辑层。除了基础的单元测试,开始注重状态转移测试。
6. 课程收获
- 我掌握了从需求分析、UML建模、代码实现到自动化测试的完整现代软件开发生命周期。
- 熟练掌握了 Java 核心技术(多线程、集合类)、版本控制(Git)、自动化测试(JUnit)、构建工具管理,以及大模型辅助开发的现代技能。
- 经历了无数个对拍查 Bug、找死锁、调优性能的夜晚,我的心智更加坚韧,面对复杂庞大的代码库不再感到恐惧,而是能用系统性的逻辑去抽丝剥茧。