上一篇我们用AI对购物车需求生成了五种方法的对象模型,最终以RDD+用例驱动作为主线,识别出以下对象。
CartController(边界对象) CartService(应用服务) Cart(购物车) CartItem(购物车项) Product(商品) CartRepository / ProductRepository(基础设施)
接下来要解决的问题是:「这些对象之间是如何协作的?它们之间的关系是什么?」
这是分析模型的最后一环,也是连接分析和设计的关键桥梁。
本环节的挑战
传统做法
确定对象间关系分两步:
「确定协作关系」:基于用例,推演对象间的交互流程,用时序图或通信图描述 「确定静态关系」:从协作中推导出对象间的静态关系类型(组合、聚合、关联、依赖)
传统做法的痛点在于「画图耗时」和「遗漏难查」:
手动画时序图费时费力,修改一个步骤可能要重画整张图 对象间的循环依赖、职责不均衡等问题,靠肉眼检查很容易遗漏 关系类型的判断(组合还是聚合?关联还是依赖?)需要经验和反复推敲
为什么适合AI辅助
「时序图可以文本化」:Mermaid语法让AI可以直接生成时序图,无需画图工具 「关系推导有规则可循」:从协作特征到关系类型的映射是确定性的,AI很擅长 「合理性检查是系统化的」:循环依赖检测、职责均衡检查等,本质上是结构化分析
AI辅助的具体操作
第一步:生成时序图
「场景」:基于已识别的对象,生成用例的对象交互时序图。
「Prompt」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
基于以下对象和用例,请生成时序图(MermaidsequenceDiagram语法)。对象列表:-CartController:接收HTTP请求-CartService:业务协调-Cart:购物车管理-CartItem:购物车项-Product:商品信息-CartRepository:购物车数据访问-ProductRepository:商品数据访问用例:用户添加商品到购物车主流程:1.用户发起添加请求(userId,productId,quantity)2.系统获取购物车3.系统获取商品信息4.系统检查商品库存5.系统将商品添加到购物车(如已存在则累加数量)6.系统保存购物车7.系统返回购物车信息替代流程:-4a.库存不足:返回错误提示-3a.商品不存在:返回错误提示-1a.用户未登录:引导登录请确保:-每个步骤都明确标注消息的发送者和接收者-替代流程使用alt/opt块表示
「AI的输出」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
sequenceDiagramparticipantUseras用户participantCCasCartControllerparticipantCSasCartServiceparticipantCRasCartRepositoryparticipantPRasProductRepositoryparticipantPasProductparticipantCartasCartUser->>CC:addToCart(userId,productId,quantity)CC->>CS:addToCart(userId,productId,quantity)CS->>CR:findByUserId(userId)CR-->>CS:CartCS->>PR:findById(productId)PR-->>CS:Productalt商品不存在CS-->>CC:ProductNotFoundExceptionCC-->>User:"商品不存在"else库存不足CS->>P:checkStock(quantity)P-->>CS:falseCS-->>CC:InsufficientStockExceptionCC-->>User:"库存不足"else正常流程CS->>P:checkStock(quantity)P-->>CS:trueCS->>Cart:addItem(productId,quantity)CS->>CR:save(Cart)CS-->>CC:CartCC-->>User:购物车信息end
AI一次就生成了完整的时序图,包括正常流程和替代流程。在传统流程中,这张图需要手动绘制至少30分钟。
「人的判断」:检查交互流程是否符合业务逻辑。比如,购物车为空时是否需要先创建?这取决于你的业务规则。
第二步:生成类关系图
「场景」:基于时序图中的交互关系,推导出对象间的静态关系。
「Prompt」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
基于以下时序图中展示的对象交互,请推导对象间的静态关系,生成类关系图(MermaidclassDiagram语法)。请按照以下规则判断关系类型:-组合(Composition):整体负责部分的生命周期,部分不能独立存在-聚合(Aggregation):整体包含部分,但部分可以独立存在-关联(Association):对象间有持久的引用关系-依赖(Dependency):临时性的使用关系(如方法参数)对每个关系,请说明判断依据。同时请为每个类列出:-核心属性-核心方法-关系类型和基数(1:1,1:N,N:M)
「AI的输出」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
classDiagramclassCartController{-cartService:CartService+addToCart(userId,productId,quantity)+removeFromCart(userId,cartItemId)+getCart(userId)}classCartService{-cartRepository:CartRepository-productRepository:ProductRepository+addToCart(userId,productId,quantity)Cart+removeFromCart(userId,cartItemId)void+updateQuantity(userId,cartItemId,quantity)void+getCart(userId)Cart+clearCart(userId)void}classCart{-cartId:String-userId:String-items:List~CartItem~+addItem(productId,quantity)+removeItem(cartItemId)+updateQuantity(cartItemId,quantity)+clear()+getTotalAmount()BigDecimal}classCartItem{-itemId:String-productId:String-quantity:int+getSubtotal()BigDecimal}classProduct{-productId:String-name:String-price:BigDecimal-stock:int+checkStock(quantity)boolean+decreaseStock(quantity)void}classCartRepository{<<interface>>+findByUserId(userId)Cart+save(cart)void}classProductRepository{<<interface>>+findById(productId)Product}CartController-->CartService:依赖CartService-->CartRepository:依赖CartService-->ProductRepository:依赖CartService-->Cart:依赖CartService-->Product:依赖Cart"1"*--"*"CartItem:组合CartItem-->Product:依赖
AI还会给出每个关系的判断依据:
「人的判断」:Cart和CartItem是组合还是聚合?如果你的业务中CartItem需要独立查询(比如「查看某个用户购买最多的商品」),可能需要调整为聚合关系。这取决于业务语义。
第三步:合理性验证
AI不仅能生成图,还能充当「设计评审」的角色。
「Prompt」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
请对以下购物车系统的对象关系进行设计评审,检查以下问题:1.循环依赖:对象之间的依赖关系是否有环?2.职责均衡:是否有某个对象方法过多(超过8个)或职责过重?3.信息专家原则:每个职责是否分配给了拥有相关信息的对象?4.遗漏对象:是否有行为无法归属到任何现有对象?5.关系合理性:关系类型判断是否正确?对象关系:-CartController依赖CartService-CartService依赖Cart,Product,CartRepository,ProductRepository-Cart组合CartItem(1:N)-CartItem依赖Product对象方法:-CartController:addToCart,removeFromCart,getCart(3个方法)-CartService:addToCart,removeFromCart,updateQuantity,getCart,clearCart(5个方法)-Cart:addItem,removeItem,updateQuantity,clear,getTotalAmount(5个方法)-CartItem:getSubtotal(1个方法)-Product:checkStock,decreaseStock(2个方法)
「AI的输出」:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
设计评审结果:✅循环依赖:未发现。依赖方向为Controller→Service→Domain→Repository,单向无环。✅职责均衡:所有对象方法数均在合理范围内。⚠️信息专家原则:有一个问题——Cart.getTotalAmount()需要计算总金额,但CartItem只存了productId和quantity,不知道商品价格。Cart如何获取价格信息?建议:CartItem应该存储商品的价格快照(productPrice),这样Cart可以直接通过CartItem计算总金额,无需回查Product。这也解决了商品价格变动后购物车价格不一致的问题。⚠️遗漏对象——CartItem.getSubtotal()返回的是CartItem的小计金额,但没有价格来源。如果CartItem不存productPrice,那getSubtotal()无法独立计算。建议:CartItem增加productPrice和productName属性,作为添加商品时的价格快照。⚠️关系合理性——CartItem→Product标记为「依赖」,但实际上CartItem存储了productId,这是一个持久的引用关系。如果后续需要通过CartItem查询Product详情,应该标记为「关联」。
AI发现了三个设计问题,其中「CartItem应存储价格快照」是一个「非常有经验的设计决策」——很多开发者会在第一次设计时忽略这个问题,直到编码阶段才发现购物车的价格计算有bug。
「人的判断」:决定是否采纳AI的建议。价格快照方案虽然解决了价格一致性问题,但也带来了数据冗余。如果你的业务允许实时同步价格,可以不采纳。
第四步:修正后的最终模型
根据评审结果,修正模型后让AI重新生成:
「Prompt」:
1 2 3 4 5 6
根据以下评审意见,修正之前的类关系图:1.CartItem增加productPrice和productName属性(价格快照)2.CartItem→Product的关系从「依赖」改为「关联」3.CartItem.getSubtotal()使用productPrice*quantity计算请生成修正后的类关系图。
修正后的 CartItem:
1 2 3 4 5 6 7 8
classCartItem{-itemId:String-productId:String-productName:String←新增:商品名称快照-productPrice:BigDecimal←新增:商品价格快照-quantity:int+getSubtotal()BigDecimal}
这个迭代过程——「生成 → 评审 → 修正」——在传统流程中可能需要一轮设计评审会议,现在只需要几次对话。
最佳实践
「1. 先生成时序图,再推导类关系图」
时序图描述的是动态行为(谁做了什么),类关系图描述的是静态结构(谁和谁有什么关系)。从动态推导静态比反过来更自然——先搞清楚对象怎么协作,再确定它们之间的静态关系。
「2. 让AI做第一轮评审,人做第二轮」
AI的评审能捕获结构性的问题(循环依赖、职责不均衡、信息专家违反),但无法判断业务语义是否正确。比如CartItem是否需要存价格快照,取决于你的业务规则。AI提出建议,人做决策。
「3. 把评审意见作为对话而非指令」
不要只问「有没有问题」,而是追问「为什么」:
1 2
你建议CartItem存储价格快照。那如果商品有促销活动,购物车中的价格是否也应该反映促销价?如果应该,价格快照方案还能适用吗?
这种对话能帮你理解设计决策的边界条件,而不仅仅是得到一个yes/no的答案。
「4. 注意AI生成时序图的粒度」
AI可能生成过于详细的时序图(把每一步数据库操作都画出来),也可能过于简略(只画了高层交互)。在Prompt中明确粒度:是「业务层面的对象协作」还是「包含技术细节的完整调用链」。
本环节AI的能力边界
AI做得好的
「快速生成时序图和类关系图」:Mermaid格式可直接渲染,省去画图时间 「关系类型判断」:根据协作特征推导关系类型,规则明确,判断准确 「结构性问题检测」:循环依赖、职责不均衡等结构性问题,AI能系统化检查 「发现经验性设计问题」:如价格快照、CartItem遗漏等
AI做不好的
「业务语义判断」:组合还是聚合,取决于业务规则而非技术规则 「关系基数的精确判断」:1:1 还是 1:N,需要业务上下文 「设计权衡」:快照方案vs实时同步方案,各有优劣,AI无法替你决策
必须人做的
「协作流程的业务语义验证」:时序图是否符合业务实际 「关系类型的最终确认」:结合业务规则确定关系类型 「设计决策的权衡取舍」:接受还是拒绝AI的建议
总结
本文演示了AI如何辅助关系建模:
「生成」:从用例描述自动生成时序图和类关系图。
「评审」:检测循环依赖、职责不均衡、信息专家违反、遗漏对象等设计问题。
「迭代」:根据评审意见快速修正模型,几轮对话完成传统流程中一轮评审会议的工作。
「核心流程」:生成时序图 → 推导类关系图 → AI评审 → 修正 → 人的最终确认。
分析模型至此完成。在下一篇中,我们将展示AI如何将分析模型转化为引入设计原则和设计模式的设计模型。
夜雨聆风