275
社区成员
发帖
与我相关
我的任务
分享1. 正向建模的核心流程
本单元通过图书馆管理系统实践了 “需求分析→UML 建模→代码实现” 的正向开发流程:
需求分析:明确系统功能(借阅、预约、信用分等)、业务规则(借阅限制、状态转移)及输出要求,如指导书中定义的书籍位置、借阅流程和信用分计算规则。
UML 建模:使用类图、状态图、顺序图进行架构设计。类图定义系统核心实体(Book、User、LibrarySystem 等)及其关系;状态图描述书籍状态转移(如从普通书架到用户手中);顺序图模拟用户与系统的交互流程(如预约 - 取书过程)。
代码实现:根据 UML 模型编写代码,确保类、属性、方法与模型一致,如Book类的状态转移方法move对应状态图中的迁移,LibrarySystem类的handleRequest方法处理用户请求,实现顺序图中的消息传递。
2. 正向建模的关键价值
提前规划架构:通过 UML 模型明确模块划分(如BookShelf负责书架管理,User处理用户逻辑),避免代码冗余或逻辑混乱。
保证设计一致性:UML 模型作为开发蓝图,确保代码实现符合需求,如User类的信用分计算(updateScore方法)严格遵循指导书中的加分 / 减分规则。
便于沟通与迭代:UML 图作为可视化工具,便于团队理解系统设计,同时为后续功能扩展(如新增书籍类型)提供清晰的扩展点。
1. 系统架构设计解析
系统采用模块化设计,核心模块及职责如下:
实体层
Book:管理书籍状态(位置、预约信息、历史轨迹),实现move方法处理位置转移。
User:维护用户信用分、借阅记录及预约状态,如canBorrowB方法检查 B 类书借阅权限。
功能模块层
BookShelf:管理普通书架和热门书架的书籍存储与检索,如takeBook方法获取可借阅书籍。
AppointmentOffice:处理预约逻辑,包括预留书籍和过期清理(purgeExpired方法)。
LibrarySystem:系统核心控制器,整合各模块功能,通过handleRequest处理用户请求,调用Trigger注解实现状态转移。
工具层
Transaction:记录书籍移动轨迹,ReadingRoom管理阅览室书籍,BorrowReturnOffice处理借还流程。
2. UML 模型与代码的追踪关系
类图与代码的一致性
类图中Book类的属性(isbn、currentState)与代码中Book类的字段完全对应;User类的方法(addBorrowedBook、returnBook)在类图中均有定义。
关联关系方面,LibrarySystem通过组合关系引用BookShelf、User等类,与类图中的关联关系一致。
状态图与代码的映射
状态图中书籍的状态(BOOKSHELF、USER、APPOINTMENT_OFFICE)对应LibraryBookState枚举,Book类的move方法通过@Trigger注解实现状态转移,如@Trigger(from = "BOOKSHELF", to = "USER")对应借书操作的状态变化。
顺序图与方法调用的对应
顺序图中 “用户预约 - 系统处理” 的消息路径对应LibrarySystem的handleOrder方法调用User的setPendingReservation方法,实现预约逻辑。
3. 设计与实现的差异与调整
简化设计:代码中LibrarySystem的orderNewBook和getOrderedBook方法为空实现,可能因 UML 模型中未详细定义预约流程的交互细节,需在代码中补充具体逻辑。
动态逻辑补充:UML 模型未完全覆盖信用分计算的时间逻辑(如逾期天数计算),代码中User的checkPoint方法通过日期差值动态处理扣分,体现了模型与代码的互补性。
1. 分阶段输入需求,逐步细化模型
初始需求拆解
:将复杂场景(如图书馆管理)分解为核心实体(书籍、用户)和业务流程(借阅、预约),要求大模型生成初始类图。例如:
“设计一个图书馆管理系统,包含书籍、用户、书架等实体,实现借阅、还书、预约功能,生成 UML 类图。”
规则具体化
:补充业务规则(如信用分计算、借阅限制),引导大模型细化类的属性和方法。例如:
“B 类书每人最多借 1 本,C 类书每个 ISBN 最多借 1 本,在 User 类中添加借阅限制检查方法。”
2. 利用示例与约束规范模型输出
提供 UML 规范:指定模型元素的命名规则(如类名首字母大写,方法名驼峰式)、关系类型(组合、关联),避免大模型生成不规范的设计。
示例引导
给出部分类的代码结构,让大模型参考实现。例如:
// 示例:Book类的基本结构
public class Book {
private String isbn;
private String state;
public void move(String newState) { /* 状态转移逻辑 */ }
}
要求大模型基于此扩展完整的类定义。
3. 迭代验证与领域知识注入
模型验证:针对大模型生成的架构,检查是否满足核心需求。例如:
“检查预约功能是否支持逾期自动取消,状态图中是否包含预约过期的转移路径。”
领域知识补充:当大模型遗漏业务细节时(如书籍移动轨迹的记录方式),手动注入领域知识,要求模型调整。例如:
“每本图书需要记录历史移动轨迹,在 Book 类中添加 Transaction 列表,并实现记录方法。”
4. 复杂场景的分层设计策略
分层抽象:将系统分为 “实体层 - 功能层 - 控制层”,先设计实体类(Book、User),再实现功能模块(BookShelf、AppointmentOffice),最后整合到控制层(LibrarySystem)。
状态与行为分离:在状态图中明确状态转移条件(如信用分≥60 才能借阅),引导大模型在代码中通过@Trigger和Guard条件实现,如User类的canBorrowB方法作为借阅操作的 Guard 条件。
5. 大模型的局限性与人工调整点
业务规则深度理解不足:大模型可能无法完全覆盖复杂规则(如信用分扣分的时间计算),需人工在代码中补充checkPoint方法的日期逻辑。
架构优化建议:大模型生成的初始设计可能缺乏性能考虑(如书籍检索效率),需人工调整数据结构(如BookShelf使用HashMap加速 ISBN 查询)。
架构特点:基于语法树的层次化分解,核心是表达式解析与计算的分离。 示例:
// 表达式节点接口
interface ExpressionNode {
double evaluate(); // 计算值
String simplify(); // 化简表达式
}
// 具体节点实现
class NumberNode implements ExpressionNode {...}
class BinaryOpNode implements ExpressionNode {...}
class FunctionNode implements ExpressionNode {...}
// 解析器
class ExpressionParser {
ExpressionNode parse(String input); // 构建语法树
}
设计思维:
分治策略:将复杂表达式拆解为原子节点(如数字、变量)和复合节点(如运算符、函数),通过递归组合实现整体计算。
单一职责:ExpressionNode接口分离计算(evaluate)和化简(simplify)逻辑,避免功能耦合。
局限性:缺乏状态管理(如表达式计算过程中的中间状态),扩展性受限于固定的节点类型。
架构特点:基于生产者 - 消费者模式的异步调度,核心是请求处理与资源分配的解耦。 示例:
// 请求队列(共享资源)
class RequestQueue {
private final BlockingQueue<Request> queue = new LinkedBlockingQueue<>();
public void addRequest(Request req) {...}
public Request getRequest() {...}
}
// 电梯线程(消费者)
class Elevator implements Runnable {
private final RequestQueue queue;
public void run() {
while (true) {
Request req = queue.getRequest();
moveTo(req.getFloor()); // 处理请求
}
}
}
// 调度器(生产者)
class Scheduler {
private final RequestQueue queue;
public void dispatch(Request req) {
queue.addRequest(req); // 分配请求
}
}
设计思维:
异步通信:通过BlockingQueue实现线程间解耦,避免直接依赖(如电梯与乘客的强绑定)。
并发控制:使用线程安全队列处理多请求,支持多电梯并行调度。
状态管理:引入电梯状态机(如运行、开门、关门),通过状态转移处理复杂场景(如捎带)。
演进:相比第一单元,增加了时间维度的处理(请求时序、电梯运行时间)和并发协作。
架构特点:基于图的关系建模,核心是实体关系与算法实现的分离。 示例:
// 图结构
class SocialNetwork {
private final Map<Integer, User> users = new HashMap<>(); // 用户节点
private final Map<Integer, List<Integer>> friendships = new HashMap<>(); // 边
public void addFriend(int userId1, int userId2) {...} // 添加关系
public int getShortestPath(int userId1, int userId2) {...} // 最短路径
}
// 用户实体
class User {
private final int id;
private final List<Integer> friends = new ArrayList<>();
public void sendMessage(User target, String msg) {...} // 消息传递
}
设计思维:
数据抽象:将社交关系抽象为图(节点 = 用户,边 = 关系),支持高效查询(如最短路径、连通分量)。
算法分离:图算法(如 Dijkstra)与业务逻辑(如消息传递)解耦,通过接口封装实现替换(如更换路径算法)。
性能优化:使用HashMap存储用户和关系,降低查询复杂度(如 O (1) 查找用户)。
演进:相比第二单元,从时序控制转向大规模数据关系处理,引入图论算法优化。
架构特点:基于领域模型的状态驱动,核心是业务规则与状态流转的统一。 示例:
// 领域实体
class Book {
private LibraryBookState state; // 状态
private final List<Transaction> history = new ArrayList<>(); // 历史轨迹
@Trigger(from = "BOOKSHELF", to = "USER")
public void borrow(User user) {
state = LibraryBookState.USER;
history.add(new Transaction("BORROW", user.getId()));
}
}
// 状态管理
enum LibraryBookState {
BOOKSHELF, USER, APPOINTMENT_OFFICE, READING_ROOM
}
// 系统服务
class LibrarySystem {
@Autowired
private BookShelf bookShelf;
@Autowired
private AppointmentOffice appointmentOffice;
public void handleRequest(User user, Request req) {
// 根据请求类型委派给不同模块
if (req.getType() == RequestType.BORROW) {
bookShelf.borrowBook(user, req.getBookId());
} else if (req.getType() == RequestType.ORDER) {
appointmentOffice.makeAppointment(user, req.getBookId());
}
}
}
设计思维:
领域建模:将图书管理的核心概念(图书、用户、借阅、预约)抽象为领域对象,通过注解(@Trigger)显式定义状态流转规则。
事件溯源:Transaction记录操作历史,支持审计和状态恢复,确保数据一致性。
模块化协作:通过LibrarySystem整合BookShelf、AppointmentOffice等模块,实现复杂业务流程(如预约 - 借阅联动)。
演进:相比第三单元,从静态关系管理转向动态业务流程控制,引入状态机和事件驱动机制。
结构化分解(第一单元):通过分治策略拆解问题,建立基础的层次化结构。
并发与异步(第二单元):引入时间维度和并发控制,处理多任务协作。
数据驱动优化(第三单元):基于抽象数据结构(如图)优化大规模关系处理。
领域驱动设计(第四单元):聚焦业务本质,通过领域模型和状态机统一业务规则与实现。
共同模式:从简单到复杂,逐步引入抽象层(如接口、注解)和中间层(如队列、服务),实现关注点分离和模块解耦。
递归下降与表达式解析 —— 语法分析与分治思维
核心内容:通过递归下降法实现复杂表达式的解析与化简,重点掌握语法树构建、递归分治策略及接口抽象。 技术收获:
递归下降解析原理:将表达式语法规则转化为递归函数,如通过parseExpression()、parseTerm()等方法逐层拆解表达式(如a*(b+c)分解为运算符和操作数),实现语法树的动态构建。
接口与实现分离:定义ExpressionNode接口统一表达式节点行为(计算evaluate、化简simplify),通过NumberNode、BinaryOpNode等具体类实现多态,体现面向对象的封装与扩展能力。
分治思想应用:将复杂问题(表达式计算)分解为原子问题(单节点求值),通过递归组合结果,如二叉表达式树的后序遍历求值。 思维提升:建立 “问题拆解 - 抽象建模 - 递归组合” 的解决思路,理解语法分析在编译器、解释器中的基础作用。
多线程电梯调度 —— 并发控制与异步编程
核心内容:基于多线程实现电梯调度,重点掌握线程安全、生产者 - 消费者模式及并发协作。 技术收获:
线程安全设计:使用BlockingQueue实现请求队列,通过wait/notify或Lock机制处理线程同步(如电梯与调度器的请求传递),避免竞态条件(如多电梯同时响应同一请求)。
生产者 - 消费者模式
:调度器作为生产者将请求放入队列,电梯作为消费者处理请求,解耦任务分配与执行,如:
// 调度器(生产者) requestQueue.put(new Request(floor, type)); // 电梯(消费者) Request req = requestQueue.take();
状态机与并发状态管理:定义电梯状态(运行、开门、关门),通过状态转移处理复杂逻辑(如捎带请求、空闲调度),确保多线程环境下状态一致性。 思维提升:理解并发编程的复杂性,掌握 “资源隔离 - 同步控制 - 异步解耦” 的设计原则,培养时序逻辑与线程安全意识。
JML 规格与 Junit 测试 —— 形式化设计与验证
核心内容:使用 JML(Java Modeling Language)描述接口规格,并通过 Junit 进行测试验证。 技术收获:
JML 规格描述:通过前置条件(requires)、后置条件(ensures)和不变式(invariant)精确定义方法行为。比如:
/*@ requires exists u1, u2 in users; @ ensures friendships[u1].contains(u2) && friendships[u2].contains(u1); @*/ void addFriend(int id1, int id2);
Junit 测试驱动开发(TDD):根据 JML 规格编写测试用例,通过@Test验证边界条件(如空指针、重复添加好友),确保代码实现与规格一致。
契约式设计(Design by Contract):JML 规格作为代码与调用者的 “契约”,强制保证接口行为的正确性,减少后期调试成本。 思维提升:从 “实现功能” 转向 “验证正确性”,理解形式化方法在大型软件项目中的质量保障作用,培养 “规格先行,测试跟进” 的工程习惯。
UML 建模与正向开发 —— 架构设计与模型驱动
核心内容:使用 UML(类图、状态图、顺序图)进行正向建模,实现图书管理系统的架构设计与代码追踪。 技术收获:
类图与领域建模:通过类图定义系统核心实体(Book、User、LibrarySystem)及其关系(组合、关联),如LibrarySystem组合BookShelf和AppointmentOffice,体现模块化设计。
状态图与状态机实现:通过状态图描述图书状态转移(如BOOKSHELF→USER),结合@Trigger注解在代码中实现状态变更逻辑,确保业务规则与模型一致。
顺序图与交互流程:通过顺序图模拟用户与系统的交互(如预约 - 取书流程),指导接口设计(如orderNewBook、getOrderedBook方法的消息传递)。
模型与代码的追踪:UML 模型作为蓝图,代码实现需与类图的属性、方法及关系严格对应,如Book类的move方法必须匹配状态图中的迁移触发条件。 思维提升:掌握 “需求分析→UML 建模→代码实现” 的正向开发流程,理解模型在复杂系统设计中的可视化与架构规划作用,培养从抽象到具体的系统设计能力。
整体收获:从编码到工程化的能力跃迁
方法论升级:从 “面向过程” 到 “面向对象” 的思维转变,通过封装、继承、多态解决复杂问题,结合 UML 和 JML 实现 “模型 - 规格 - 代码” 的三位一体设计。
工程化意识:理解大型软件项目的协作规范(如模块化、接口契约、测试验证),掌握多线程、状态管理等复杂场景的解决方案。
问题分解能力:从递归下降的语法分析,到多线程的并发控制,再到 UML 的系统建模,逐步培养 “复杂问题分层拆解、核心逻辑抽象建模” 的思维习惯。
工具与技术栈:熟练使用 StarUML、Junit、JML 等工具,理解编程不仅是代码实现,更是 “需求 - 设计 - 验证” 的完整工程流程。
本课程通过渐进式项目实践,将理论知识与工程能力深度结合,为后续大型软件系统的设计与开发奠定了坚实基础。