做需求分析的朋友大概率都遇到过这种场面:手里攥着一份三四十页的需求规格说明书,甲方催着要类图、用例图,而你只能一个词一个词地读,把名词圈出来当归类、把动词圈出来当方法,读到第三页就已经分不清“订单”到底该是一个类还是一个属性。UML 建模里最枯燥、最容易出错的环节,往往不是画图本身,而是从自然语言需求到模型元素的这一步翻译。Visual Paradigm 里的文本分析(Textual Analysis)功能,就是冲这个痛点来的:它把需求文本喂进去,用词性标注和启发式规则把候选的类、属性、操作、用例、参与者挑出来,你再人工筛选一遍,直接生成图元。说白了,它干的是“粗筛”的活,剩下“精修”还得靠人。这篇内容适合三类人看:刚接触 UML、不知道从哪下手的建模新手;手上有大量存量需求文档、想批量提取模型元素的老手;以及带团队、想统一需求到模型转换规范的技术负责人。下面我按自己实际使用的顺序,把这套流程拆开讲。
1. 文本分析到底在解决什么问题
1.1 手工建模的真实痛点在哪里
很多人以为 UML 建模难在语法,其实难在“从哪开始”。一份典型的需求文档,写的是业务语言,比如“客户提交订单后,系统校验库存,若库存不足则提示补货,若充足则锁定库存并生成待支付订单”。这里面藏着类(客户、订单、库存)、操作(提交、校验、锁定、生成)、状态(不足、充足、待支付)、以及一条业务流程。有经验的人能在脑子里完成这层映射,但这个过程是隐性的、不可复现的,换个人来做,切分粒度就变了。
手工做这件事有三个绕不开的坑。第一是遗漏,读到后面忘了前面,尤其是跨章节的同一个概念用了不同叫法,“客户”和“用户”到底是不是一个东西,全靠记忆。第二是粒度失控,同一个“订单”,有人建成一个类,有人拆成订单头和订单明细两个类,没有一个客观起点。第三是成本,一份中等规模的需求文档,纯手工提取候选元素再整理成图,两三天是常态,而且改一版需求就得重来一遍。
文本分析的价值不在于替你做完,而在于给你一个可讨论的起点。它把所有名词、动词摆到台面上,你和业务方可以指着列表说“这个不要”“这个合并”,比对着空白画布吵架效率高得多。
1.2 文本分析的底层逻辑:它凭什么能识别出类
理解原理,你才知道什么时候该信它、什么时候该推翻它。这类工具的核心是三件事叠加:词性标注、领域词典、启发式规则。
词性标注是第一步,把句子切成词并标注词性。名词短语是候选类或属性的主要来源,动词是候选操作或关系的来源,形容词往往对应属性值或状态。比如“系统锁定库存”这句话,“系统”是名词,“锁定”是动词,“库存”是名词,工具就会把“库存”标为候选类,把“锁定”标为候选操作,并尝试建立“系统对库存执行锁定”的关联。
领域词典是第二步,也是准确率的关键。通用词性标注器不认识你的业务黑话,比如“工单池”“撮合引擎”“履约单”,它可能把“工单池”拆成“工单”和“池”,也可能把“履约单”当成一个陌生词丢掉。词典的作用就是告诉工具:这是一个不可分割的术语,请整体处理,并且它属于类。
启发式规则是第三步,把语言结构映射到模型结构。常见的映射关系大致如下:
| 文本中的语言模式 | 工具倾向识别的模型元素 | 需要人工确认的点 |
|---|---|---|
| 名词或名词短语(出现频次高) | 类 | 是否只是属性、是否与已有类重复 |
| 名词短语(仅服务于某个类) | 属性 | 是否是独立实体、有无自己的生命周期 |
| 动词或动宾结构 | 操作 / 用例 | 是类的方法还是跨对象的用例 |
| “包含”“由……组成” | 组合 / 聚合 | 组合还是聚合,取决于生命周期是否绑定 |
| “是一种”“属于……的一种” | 泛化 | 是否真的存在行为差异 |
| “由……负责”“……操作” | 参与者 | 是外部角色还是内部模块 |
| 形容词、状态词 | 属性值 / 状态 | 是否值得建状态机 |
提示:这套映射是启发式的,不是语义理解。工具并不知道“库存”和“仓库”的区别,它只认语法位置和词典。所以别指望它一次识别到位,把它当“高级查找替换”更贴切。
1.3 什么场景适合用,什么场景别硬上
不是所有需求文本都值得跑一遍文本分析。用错了场景,你会花更多时间去清理噪音。
| 场景 | 是否推荐 | 原因 |
|---|---|---|
| 结构化较好的需求规格说明书 | 强烈推荐 | 主谓宾完整,术语统一,识别率高 |
| 用户故事、用例描述 | 推荐 | 句式固定,“作为……我希望……以便……”,参与者识别准 |
| 会议记录、聊天记录 | 不推荐 | 口语化严重,指代多,噪音远超收益 |
| 纯中文长句、无标点段落 | 谨慎使用 | 分词和词性标注容易崩,需先预处理 |
| 已有初步类图、想查漏 | 推荐 | 拿识别结果和现有模型比对,补漏效果好 |
| 从零开始、需求本身模糊 | 不推荐 | 需求不清,识别出来也是一堆废词 |
我个人的判断标准很简单:文本里的每个句子能不能拆出清晰的主谓宾。能,就跑一遍;不能,先花时间把需求理清楚,比跑工具划算。
2. 上手前的环境与材料准备
2.1 工具入口与工作区准备
在 Visual Paradigm 里,文本分析功能通常在菜单的 Tools 下能找到,叫 Textual Analysis。点进去会弹出一个独立的工作面板,左边是文本编辑区,右边是候选元素列表,中间是分析按钮。第一次用建议先建一个独立的实验项目,不要直接塞进正式项目里,原因很简单:候选元素会大量堆积在模型树里,清理起来很烦。
工作区准备有三个动作值得做。第一,关掉自动同步。有些版本会把识别出的候选元素实时写入模型,结果模型树里瞬间多出几十个“候选类”,命名还带着括号和问号。第二,确认语言设置。工具的词典默认偏英文,中文文本的处理效果要单独验证,这一点后面会细说。第三,预留一张空白类图。识别完成后,把候选元素拖到一张专门的草图上,和正式模型分开,筛选完再合并,这个习惯能省掉大量返工。
另外提醒一句,不同版本的功能位置和叫法会有差异,有的版本把它归在“需求管理”相关入口下,有的版本需要先创建一个文本分析工程文件。找不到入口时,用帮助里的关键词搜一下比翻菜单快。
2.2 需求文本的预处理,这一步决定成败
绝大多数人失败在第一步:直接把 Word 文档整篇复制进去。结果工具识别出一堆页眉、页脚、编号、版本记录,候选列表长得像乱码。预处理不是可选项,是必选项。
我的做法是四步清洗。第一,去掉所有非业务内容,包括文档头、修订记录、目录、图表标题、附录里的接口字段表。第二,统一术语。全文搜一遍同义词,把“用户/客户/会员”统一成一个词,把“下单/创建订单/提交订单”统一成一个动作。这一步手工做,但收益最高,因为工具不会帮你合并语义。第三,拆分超长句。一个句子里塞了三个动作和四个对象,词性标注大概率出错。把复合句拆成单句,每个句子只表达一个主谓宾。第四,补全省略主语。需求文档爱写“校验通过后,生成订单”,谁校验?谁生成?补成“系统校验支付信息通过后,系统生成订单”,识别质量立刻不一样。
举个具体的对比。“若库存不足则提示补货”这句话,工具可能把“库存不足”整体当名词,把“提示”当动词,把“补货”当名词,然后给你三个莫名其妙的东西。改成“系统检查库存。如果库存数量小于安全库存,系统提示补货。”之后,主谓宾清晰,“系统”是参与者,“库存”是类,“检查”是操作,“提示”是操作,识别结果直接可用。
注意:预处理阶段不要为了迁就工具去改业务语义。如果一句话本身就模糊,应该回头找业务方确认,而不是自己编一个主语填进去。工具的识别结果会放大需求本身的模糊性。
2.3 领域词典和停用词表怎么维护
词典是这个功能里最值得投入时间的地方,而且它是可以复用的资产。一个项目做完,词典留着,下个项目同类业务直接导入,准确率会明显提升。
领域词典要加三类词。第一类是业务专有名词,比如行业里的特定单据名、特定角色名,这些词通用词典肯定不认识。第二类是复合术语,就是那种拆开就变味的词,比如“对账单”不能拆成“对账”和“单”,“履约保证金”不能拆成三个词。第三类是容易误判的词,比如某些名词在业务里其实是状态值,不该建成类,可以提前标注。
停用词表要加两类。第一类是无信息量的通用词,比如“系统”“平台”“功能”“信息”“数据”,这些词几乎每句话都有,如果都识别成类,你的候选列表会被垃圾填满。第二类是文档结构词,比如“如下所示”“详见附录”“本章描述”,纯属排版噪音。
维护方式上,我习惯用一张 Excel 表管理,两列:词条、类型(类/属性/忽略)。每次做完一个项目就追加一批,半年下来能攒出几百条,基本覆盖所在行业的常用术语。这个投入产出比非常高,比每次从头调参数划算得多。
3. 文本分析的完整实操流程
3.1 从需求文本创建分析任务
打开文本分析面板后,第一件事是把预处理好的文本粘贴进去。这里有个细节:分段粘贴比一次性全粘好。先粘一个业务模块,分析、筛选、生成,再粘下一个模块。原因是候选元素列表一长,人的判断力会断崖式下降,看到第三十个候选类的时候你已经不想思考了。
粘贴完成后,先别急着点分析。检查一下右侧的选项设置,通常会有几个开关:是否识别类、是否识别用例、是否识别参与者、是否识别属性、是否识别关系。第一次跑,建议只开类和参与者,把属性、操作、关系先关掉。理由很实际:类和参与者是骨架,先把骨架定下来,属性和操作是往骨架上挂肉,顺序反了会做大量无用功。
设置好之后点分析,工具会在候选区列出识别结果,通常带一个频次或置信度标记。这时候不要看列表,先看总数。如果一段两千字的需求识别出两百个候选类,说明词典没配好或者文本太脏,回去改预处理,别往下走。正常比例我实测下来大概是每千字产出十五到二十五个候选类,经过人工筛选保留八到十二个,这个量级是合理的。
3.2 候选元素的筛选:名词归类和动词归操作
筛选是整个流程里最耗人力、也最体现水平的环节。工具给的是平铺列表,你要做的是分类决策。我一般按三步走。
第一步,快速剔除明显噪音。一眼就知道不是类的词直接删:通用词、文档结构词、重复词、拼写变体。这一步不纠结,凭直觉,三十秒扫一遍,能砍掉三到四成。
第二步,区分实体和属性。这是最容易出错的地方。判断标准只有一个:这个东西有没有自己的生命周期和独立标识。有,就是类;没有,就是属性。举例来说,“订单”有编号、有状态流转、能被单独查询,是类。“订单金额”只是订单的一个数值,没有独立生命周期,是属性。“收货地址”看起来像属性,但如果系统要管理地址簿、一个地址能被多个订单复用、地址本身有修改历史,那它就该独立成类。这个判断没法自动化,必须结合业务规则来定。
第三步,把动词归到正确的位置。动词的归属有三条路:如果这个动作是某个对象自己执行的,归为该类的操作;如果这个动作是多个对象协作完成的,归为用例;如果这个动作描述的是一种关系,比如“包含”“拥有”,归为关联或组合。举个例子,“计算总价”是订单自己的事,归为订单的操作;“提交订单”涉及客户、订单、库存、支付多个对象,是一个用例;“订单包含订单明细”是组合关系。同一个动词,位置不同,模型结构完全不同。
| 候选词 | 可能的归属 | 判断依据 |
|---|---|---|
| 订单 | 类 | 有独立标识、有状态、可被单独引用 |
| 订单金额 | 属性 | 依附于订单,无独立生命周期 |
| 收货地址 | 属性或类 | 看是否被复用、是否有独立管理需求 |
| 计算总价 | 操作 | 单个对象内部完成,不跨对象协作 |
| 提交订单 | 用例 | 多对象协作,有明确的业务目标 |
| 包含明细 | 组合关系 | 整体与部分生命周期绑定 |
| 库存不足 | 状态值 | 描述对象的某个状态,不是实体 |
提示:筛选时不要在候选列表里直接改名字。先标记“保留/删除/待定”,全部过完一遍再统一命名。边看边改会让你反复横跳,效率极低。
3.3 从候选元素生成图元与初步模型
筛选完,把保留的候选元素生成图元。这里有两种方式,各有适用场景。一种是逐个拖拽到图上,适合候选数量少、你想精确控制位置和分组的情况。另一种是批量生成,工具会按你勾选的元素自动建图,适合候选数量多、先出个草稿的情况。
我的习惯是批量生成打底,然后手工重排。批量生成的图基本没法看,元素挤成一团,连线乱飞,但它的价值在于元素都在图上了,接下来是整理而不是创造。整理的时候按业务模块分区,把同一个用例相关的类放一起,边界一清二楚,后面补关系会很顺。
生成之后立刻做一件事:给每个类补一句职责描述。不用长,一句话说清这个类负责什么。这句话的作用是防止类膨胀,当你写不出职责描述的时候,说明这个类本身就不成立,该合并或删除。我在一个项目里就是这么发现“订单辅助类”这种垃圾元素的,写职责的时候发现它什么也不干,纯粹是识别噪音。
3.4 参数调整:让识别粒度贴合项目需要
工具一般会提供一些影响识别粒度的设置,比如最小词频、是否合并单复数、是否识别复合名词。这些参数没有标准答案,但有一条经验规律:项目早期放宽,项目后期收紧。
早期做领域模型,你需要看到全貌,宁可多识别一些,把最小词频调低,让低频但重要的概念也能浮出来。这时候列表长一点无所谓,你有精力逐个看。到了详细设计阶段,你要的是精确,把词频门槛调高,把通用词全部扔进停用词表,只留高频核心概念,避免模型被边缘元素撑爆。
还有一个容易忽略的参数是同义词合并。有些版本支持配置同义词组,比如把“客户/用户/会员”指向同一个候选类。这个功能一定要用,因为需求文档里同义混用是普遍现象,不合并的话你会得到三个几乎一样的类,后面合并起来很痛苦。没有这个功能的话,就在预处理阶段手工统一,效果一样,只是费点事。
4. 结果校验与模型精修
4.1 怎么判断一个候选类该不该留
工具给的候选,最终留不留,我有一套自己的检查清单,四条全过才保留。
第一条,它有明确的职责吗?用一句话能说清它负责什么,且这句话里不出现“管理”“处理”“辅助”这类空词。说不清,删。
第二条,它有独立的数据吗?它自己持有一组属性,而不是完全依附于另一个类。如果它的所有属性都能平移到父类里,说明它不该独立存在。
第三条,它在业务流程里有动作吗?它是某个用例的参与者或操作对象,而不是纯粹的数据容器。纯数据容器在领域模型里往往是属性或值对象,不需要建实体类。
第四条,它和已有类的关系清晰吗?能说清是关联、聚合还是泛化。说不清关系,大概率是重复概念或者粒度错了。
这四条过下来,通常会砍掉一半以上。别心疼,模型里多一个错误类,后面每张图都要为它买单。我在一个项目里见过有人把文本分析结果全盘接受,最后类图上有六十多个类,其中二十多个从来没人引用过,纯属摆设。
4.2 关系识别的修正:从文本线索到 UML 语义
工具识别出的关系通常是“有关联”这种模糊判断,具体是哪种关系,得你根据文本线索来定。常用的对应关系有这么几组。
文本里出现“由……组成”“包含”“分为”,且部分不能脱离整体独立存在,就是组合。比如“订单由订单明细组成”,删掉订单,明细没有意义,组合。文本里出现“拥有”“关联”“对应”,且部分可以独立存在,就是聚合。比如“购物车拥有商品”,商品不依赖购物车存在,聚合。文本里出现“是一种”“属于……的一种”“分为……类型”,且子类型有额外属性或行为,就是泛化。注意,如果只是状态不同、行为完全一样,不要建泛化,用状态字段更合适。
还有一类关系工具基本识别不出来,就是依赖。依赖往往藏在“使用”“调用”“基于……计算”这类动词里,而且它通常是临时的、单向的。这类关系在类图上画虚线箭头,但如果你的模型只做到领域层,可以先不画,等详细设计再补。
| 文本线索 | 推荐关系 | 典型误判 |
|---|---|---|
| 由……组成、包含(生命周期绑定) | 组合 | 误判为普通关联,丢失整体部分语义 |
| 拥有、关联、对应(可独立存在) | 聚合 | 误判为组合,过度约束 |
| 是一种、分为……类型(有行为差异) | 泛化 | 仅状态不同也建泛化,导致类爆炸 |
| 使用、调用、基于……计算 | 依赖 | 误判为关联,把临时关系固化 |
| 一个A对应多个B | 一对多关联 | 多重性标反,方向搞错 |
修正关系的时候有个小技巧:先画一对多,再补多重性。文本里说“一个订单有多个明细”,先把线连上,方向从订单指向明细,然后在两端标 1 和 *。别一上来就纠结多重性,先把拓扑结构定下来,细节后面调。这个方法能显著降低画图时的心理负担。
4.3 和后续建模工作的衔接
文本分析的产出不应该停在类图。筛选出的类、参与者、用例,可以直接支撑后续三件事。
一是用例图。参与者是从文本里的角色名词来的,用例是从动宾结构来的,把这两者一连,用例图的骨架就有了。这时候要检查的是用例粒度,一个用例应该是一个对参与者有价值的完整目标,而不是一个步骤。“提交订单”是目标,“点击提交按钮”是步骤,后者不该成用例。
二是顺序图。类图和用例定下来之后,挑几个核心用例展开顺序图,这时候你会发现文本分析阶段漏掉的对象。这很正常,文本分析是静态的,顺序图是动态的,动态推演本来就能补静态的漏。
三是需求追溯。好的文本分析工具会保留候选元素和原文的对应关系,点一下类就能跳回那句话。这个功能在做需求变更的时候价值巨大,需求改了一句话,你能立刻定位到受影响的模型元素,不用全文重读。如果你的工具版本支持,一定要把这个追溯关系保留好,别在生成图元之后就断了。
5. 常见问题与排查技巧实录
5.1 识别结果全是噪音,候选列表没法看
这是最高频的问题,原因基本逃不出三个:文本太脏、词典没配、参数太松。排查顺序建议从文本开始,因为改文本的收益最直接。
先看候选列表里有没有大量重复词和变形词,如果有,说明预处理没做,同义词没统一。再看有没有大量“系统”“功能”“信息”这类词,如果有,停用词表没配。最后看有没有把长术语拆碎,如果有,领域词典缺词条。这三步走完,噪音通常能降七成以上。
还有一个隐蔽原因:文本里混入了表格内容。需求文档里的字段表、接口表被复制进来后,工具会把每个字段名都当候选类,瞬间产出上百个垃圾元素。解决办法很简单,粘贴前把表格全部删掉,字段信息单独用建模的方式录入,别指望文本分析处理表格。
注意:不要试图靠调参数解决文本质量问题。参数只能微调,文本脏是根因,根因不解决,怎么调都是白费。
5.2 中文文本的识别效果明显差一截
这个问题的根源在于词性标注模型的语言偏向。多数工具的默认识别引擎是为英文设计的,英文有空格分词,词性规则成熟;中文没有空格,分词本身就存在歧义,再加上业务术语多,出错是常态。
应对办法有三条,按推荐程度排序。第一条,能写英文就写英文。如果团队有英文需求文档,或者愿意在建模阶段用英文术语,识别质量会好很多,这个投入是值得的。第二条,强化词典。把中文业务术语尽可能全地加进领域词典,尤其是复合词,让工具按整词处理而不是拆开。第三条,缩短句子。中文长句是分词杀手,把句子拆到十来个字,每个句子只有一个主谓宾,识别率会明显回升。
还有一个土办法:在中文词之间加空格或者分隔符。有些工具会按空格切词,加了空格之后分词错误率大幅下降。这个办法不优雅,但对小规模文本应急很有效。做完分析再把空格去掉就行。
5.3 生成的图元堆在一起,根本没法看
批量生成之后的图,元素重叠、连线交叉,是正常现象,别慌。处理顺序是:先做自动布局,工具一般有布局功能,一键能把元素散开;再做手工分区,按业务模块把类分组,用包或者注释框圈起来;最后做连线整理,把交叉的线拉直,把不必要的关系先隐藏。
这里有个经验:先分区再连线,别反过来。元素位置没定就急着连线,线会把你锁死,动一个元素要重排一片线。先把元素摆好,位置稳定了再连,返工量小得多。另外,生成图之后立刻把图保存成草稿版本,后续精修另存新版本,别在一个图上反复覆盖,出问题回不去。
5.4 常见问题速查表
| 现象 | 最可能的原因 | 处理动作 |
|---|---|---|
| 候选类数量异常多 | 文本含表格或停用词未配 | 清理文本、补停用词表 |
| 长术语被拆成多个词 | 领域词典缺复合词条 | 补充词典,整词加入 |
| 同义概念出现多个类 | 未做同义词统一 | 预处理统一术语或配置同义词组 |
| 关系全是普通关联 | 未做关系语义修正 | 按文本线索改为组合/聚合/泛化 |
| 中文识别率低 | 分词错误、长句过多 | 拆句、加词典、必要时加分隔符 |
| 图元重叠严重 | 批量生成未布局 | 先自动布局,再手工分区 |
| 模型树里垃圾元素多 | 未建独立实验项目 | 隔离分析环境,筛选后再合并 |
5.5 几条踩过坑之后才明白的经验
别在需求还没定稿的时候跑文本分析。需求改一版,之前筛的可都要重来。等需求相对稳定,哪怕只是某个模块稳定,先对这个模块做,做完立刻产出图,锁定下来。
别把文本分析当成需求理解的替代品。工具能帮你找出名词,但找不出业务规则。规则藏在条件句里,藏在“如果……则……”里,这些东西工具识别不了,必须人工读。我一般会把文本分析放在通读一遍需求之后做,先有整体理解,再用工具查漏,顺序反过来容易被工具带偏。
保留分析记录。哪个词被判定为噪音、为什么删,简单记一笔。下次遇到同样的词,不用重新纠结。这份记录也是给团队新人最好的培训材料,比讲十遍方法论管用。
控制单次分析规模。一次分析一个模块,最多不超过三千字。超过这个量,人的判断力会明显下降,筛选质量直线下滑。
6. 我个人的使用边界和一点体会
用了一段时间之后,我对这个功能的定位越来越清晰:它是一个降低启动成本的辅助工具,不是一个自动化建模方案。它的最大价值在于把“面对空白画布”变成“面对一份待筛选的清单”,前者让人拖延,后者让人动手。至于清单上的东西对不对,还是得靠对业务的理解。
我也见过反面的用法。有人把识别结果直接当成交付物,类图生成完就提交评审,结果评审会上被问“这个类为什么存在”,答不上来。这种情况不是工具的错,是把粗筛当成了终稿。文本分析产出的所有东西,都必须过一遍人的判断,尤其是类的划分和关系的定性,这两件事目前没有任何工具能替你做好。
还有一个体会是,这个功能的收益和你的需求文档质量强相关。文档写得结构化,收益立竿见影;文档写得像散文,工具只会把混乱放大。所以如果你的团队需求文档质量一般,先花力气规范文档模板,比如强制用“角色 + 动作 + 对象 + 条件”的句式描述需求,这比研究工具参数有用得多。模板定好了,文本分析的识别率自然上去,这是连锁反应。
如果你打算在自己的项目里试,我的建议是从一个小模块开始,挑那种需求写得最清楚、业务概念最稳定的部分,跑一遍完整流程,从预处理到出图,看看产出能不能用。能用,再推广到其他模块,同时把词典和停用词表沉淀下来。不能用,就分析是文本问题还是工具问题,别急着下结论说这功能没用。很多时候问题出在输入,不在工具本身。