首页 / 资讯中心 / 文章详情

PowerDesigner类图整理:从建模规范到代码生成

PowerDesigner类图整理:从建模规范到代码生成 ★ FEATURED ARTICLE
接手一个半成品模型打开一看类图铺满整屏连线像蛛网类名有中文有英文还有拼音缩写属性类型一半是String一半是string还有varchar(50)那一刻我脑子里只有一个念头这图不是用来设计的是用来考古的。PowerDesigner 这类建模工具很多人第一次接触是在课堂上画个图书管理系统第二次接触就是接手别人的烂摊子。类图设计整理这件事看起来是把图摆整齐实际干的是把团队的建模语言统一、把隐性的设计约定显性化、把模型从示意图拉回可生成代码的工程资产。这篇东西写给三类人刚上手 PowerDesigner、需要把课程作业或者项目文档里的类图画规范的新手接手遗留模型、被一堆冗余关系和重复类折磨的中级开发者以及需要在团队里推行建模规范、但苦于没有可落地清单的技术负责人。下面所有内容都围绕一件事展开——怎么在一张类图上把结构、命名、关系、校验、输出这几件事一次性理顺让它既能给人看又能给机器用。1. 类图整理到底在整理什么1.1 一张类图最容易烂掉的三个地方我见过的烂模型问题高度集中在三个位置几乎不例外。第一个是命名双轨制失控。PowerDesigner 里每个对象都有 Name 和 Code 两个字段Name 给人看Code 给机器用。新手往往只填 NameCode 让它自动生成于是中文名变成一串拼音改了三次名字之后 Code 彻底对不上生成代码时类名全是Lei1、Lei2。第二个是关系语义漂移。泛化、实现、关联、聚合、组合、依赖六种线画出来长得差不多很多人凭手感连最后组合关系画成了普通关联聚合和组合分不清代码生成出来的字段类型和实际设计意图完全两回事。第三个是图即一切的错觉。类图只是模型的一个视图真正的信息存在模型仓库里可很多人把它当成 Visio 用画完导出一张 PNG 就交差属性类型、多重性、导航性全部缺失后面既生成不了代码也转不成数据库模型。这三个问题的共同根源是把类图当成沟通插图而不是设计源文件。一旦你接受这张图要拿去生成代码、要参与评审、要在半年后被别人接手这个前提整理的标准立刻就清晰了可读、可校验、可导出。1.2 先把图和模型分开看这是我认为最值钱的一个认知转换。在 PowerDesigner 里打开一个 OOMObject-Oriented Model左侧浏览器树里是一堆 Package、Class、Interface右侧画布是 Class Diagram。画布上删掉一个类的图形模型里的类还在反过来在浏览器里删掉类画布上的图形和它相关的连线会一起消失。搞不清这层关系的人经常在画布上拖来拖去以为整理完了结果模型里躺着一堆孤儿类。所以整理的顺序应该是自下而上的先处理模型树里的对象——去重、改名、补属性、定类型再处理画布上的布局——分组、对齐、减少交叉。反过来做等于给一堆没整理好的数据做排版白费功夫。注意整理前先做一次完整备份另存为一个带日期后缀的副本文件。PowerDesigner 的撤销栈对模型级操作支持有限批量改 Code 这类动作一旦做错回退成本极高。2. 建模前的基线设置别让默认值坑你2.1 新建 OOM 模型时必须改的几个选项很多人建模型时一路下一步默认语言选 Java然后就开工了。默认值本身没错但有几个开关不调后面全是坑。建模型时在 Model 名称之外重点看Model Options菜单 Model Model Options。在 OOM 分类下有这几项值得动选项位置默认行为建议调整原因Model Settings Name/Code case自动同步关闭自动同步避免改名时 Code 被悄悄改掉破坏已有代码映射Model Settings Generate Java import关闭打开生成代码时自动补 import省手工Data Types 默认类型映射通用类型绑定具体语言类型让String就是java.lang.String不是自定义字符串Attributes/Operations 默认可见性public按分层约定设置实体类属性默认 private减少人工改关闭 Name/Code 自动同步这一条我要单独强调。默认情况下你把 Name 从订单改成销售订单Code 可能跟着变而你之前生成的代码里类名是Order一改就对不上了。关掉同步后Name 随便改Code 保持稳定这是模型能长期维护的前提。2.2 命名基线与数据类型映射命名这件事团队里必须先吵一次架再定下来否则后面每次评审都要吵。我给的建议是三句话Name 用业务语言允许中文和空格Code 用英文驼峰全局唯一包名和目录结构对齐。具体落地时在 Model Options 里设置好 Name/Code 的大小写规则然后在模型里建一个词汇表包把所有核心概念列一遍订单、客户、商品、支付单。这一步看着多余实际是防止同一个人在不同包里把客户写成 Customer、Client、Kunde 三种。我做过统计一个两万行规模的系统如果前期没有词汇表类图里出现同义类的概率大概在三成以上。数据类型方面别在每个属性上手写java.lang.String。用Domain域来统一管理建一个 Domain 叫Name绑定String长度约束写在注释里建一个Money绑定BigDecimal精度 2 位建一个Id绑定Long。以后所有属性引用 Domain改一处全局生效。这跟数据库里用用户自定义类型是一个思路投入产出比极高。3. 类的整理从一坨方块到可读结构3.1 类的分层与分包策略打开画布第一件事不是摆位置是分包。PowerDesigner 的 Package 是可以嵌套的用好了就是天然的模块边界。我习惯按三层切边界层放对外接口和 DTO应用层放用例编排领域层放实体和值对象。每层一个 PackageCode 直接写成对应的包路径比如com.demo.order.domain。分包之后有个立竿见影的好处画布上可以用 Package 的折叠视图一张图只展开当前关注的那一层剩下的收起来。评审的时候按层过一次只看十几个类认知负担立刻降下来。包的依赖方向也要顺手定死边界层依赖应用层应用层依赖领域层领域层不依赖任何人。这条规则写在包的注释里后面用 Check Model 或者人工评审都能查。我见过最典型的坏味道是领域实体里直接引用了 Controller 层的类模型上一根虚线箭头横跨三个包代码里就是循环依赖。3.2 属性与操作的规范化写法属性整理有个很实用的顺序先补类型再定可见性最后加多重性。类型用 Domain 引用可见性按分层约定多重性处理集合。集合属性是重灾区。很多人把ListOrderItem写成属性类型OrderItem多重性留空生成代码时就变成一个对象。正确做法是类型写OrderItem多重性写0..*PowerDesigner 生成 Java 代码时会自动变成ListOrderItem或者数组。这个映射在 Model Options 的 Java 分类里能配默认是集合类型也可以改成数组。操作Operation方面别在类图里写实现但签名要完整。返回值类型、参数名、参数类型都要填。参数类型同样引用 Domain 或者已有类。我踩过的一个坑参数类型留空生成代码时是Object编译能过但等于没设计。整理的时候用 Check Model 能扫出一批无类型参数一次改完。还有个小技巧抽象类和接口要打上对应的构造型Stereotype。接口用Interface图标或者interface抽象类在类的属性里勾选 Abstract。这些小标记在代码生成和评审时都会被识别省得别人猜。3.3 去重与合并的实操判断整理遗留模型最耗时的环节是去重。画布上看着两个类不一样点进去发现属性有八成重合。我的判断流程是这样的先比属性集合重合度超过七成且语义一致考虑合并然后看引用关系被引用的地方越多合并的影响面越大越要谨慎最后看生命周期如果一个类的实例随另一个类创建销毁那是组合不是重复。合并操作在 PowerDesigner 里没有一键按钮只能手工把属性搬过去然后删掉多余类。删之前一定要用Edit Find搜一遍这个类的 Code确认没有别的关系线挂着。我吃过亏删了一个类画布上看着干净了结果模型里还有两条关联指向它生成代码时报空指针查了半天才发现是孤儿关系。4. 关系的整理四种连线别乱用4.1 泛化、实现、关联、依赖的判定顺序关系线是最容易画错的部分。我给团队的要求是画线之前先在心里过一个四问决策链。第一问是不是 is-a 关系是的话目标如果是类就是泛化Generalization实线空心三角是接口就是实现Realization虚线空心三角。这一问能挡掉大部分误用。第二问是不是整体-部分是的话再看生命周期。整体销毁部分跟着销毁用组合Composition实线实心菱形部分可以独立存在用聚合Aggregation实线空心菱形。订单和订单项是组合订单项删了就没意义部门和员工是聚合员工离职部门还在。第三问是不是长期持有引用是的话用关联Association实线可加导航箭头。比如订单持有客户引用。第四问是不是只在方法参数或者局部变量里用是的话用依赖Dependency虚线箭头。比如订单服务调用支付网关。这个顺序的价值在于它把主观判断变成了可复述的规则。评审的时候不用争我觉得这是组合直接问生命周期答案就出来了。4.2 关联类、多重性与导航性的细节多重性Multiplicity经常被忽略但它直接决定生成代码的结构。常见的取值就五个1、0..1、1..*、0..*、*。我的经验是默认写1只有确认可以为空才写0..1集合一律0..*而不是*因为*在很多语言映射里会被当成无约束语义模糊。导航性Navigability也值得说。单向关联画一个箭头双向关联画两个箭头或者不画箭头。问题是很多人画了双向箭头生成代码时只在一个类里生成了字段另一个类没有模型和代码就脱节了。整理时统一约定模型上只画单向导航需要反向查询的通过仓储或者查询方法解决。这样图和代码能一一对应。多对多且有业务属性的时候用关联类Association Class。比如学生和课程多对多中间有个选课记录带成绩和时间这时候别在两边各挂一个集合就完事老老实实建一个关联类连上去生成代码时就是一个独立的实体。这个习惯能省掉后面大量的中间表设计争论。5. 校验、导出与协作5.1 用 Check Model 把低级错误挡在提交前PowerDesigner 自带模型检查菜单在Tools Check Model。这个功能被严重低估很多人压根没用过。它能扫出来的问题包括类没有 Code、Code 重复、属性没有类型、关系两端多重性缺失、孤儿对象、循环继承等等。我的做法是把检查项固化成一张清单每次提交模型前跑一遍只勾选关键项检查项严重程度处理方式Object has no code高补 Code按命名基线填Duplicate code高合并或重命名Attribute has no data type高引用 DomainRelationship has no multiplicity中补1或0..*Circular generalization高拆继承链Unused object低确认后删除跑完检查会生成一个结果列表双击能直接定位到对象。这个流程走顺了模型质量能提升一大截而且是机器保证的不依赖人的记性。5.2 代码与文档的自动化输出模型整理到位之后输出就是顺带的事。生成 Java 代码走Language Generate Java Code勾选生成默认构造、getter/setter、注释。注意生成前选好目标目录别覆盖已有代码——PowerDesigner 默认会覆盖同名文件我建议先生成到一个临时目录用文件比对工具过一遍差异再合并。生成数据库物理模型走Tools Generate Physical Data Model。这里有个前提认知类图不是数据库设计图。实体类转表比较自然但值对象、枚举、继承结构转表都需要额外决策。我一般只把领域层的实体类转过去继承用单表或者 joined 策略在生成后手工调整别指望一键完美。文档输出走Report Report Wizard能生成 RTF 或者 HTML 格式的模型说明包含类清单、属性表、关系表。评审前导一份出来比让人装 PowerDesigner 看模型友好得多。导出图片走Edit Export Image分辨率调到 300 DPI 以上否则打印出来属性名全是糊的。6. 常见问题与排查实录6.1 高频问题速查表整理模型这几年遇到的问题翻来覆去就那些。我把高频的整理成一张表遇到直接查。现象大概率原因解决办法改了 Name生成代码类名没变Name/Code 未同步或已关闭同步手动改 Code 字段中文显示成方块或乱码画布字体不支持中文Tools General Options Fonts 换字体生成代码缺 import未开启自动 importModel Options 里打开对应开关关系线交叉严重看不清未做自动布局Symbol Auto-Layout或按包分区手工摆模型打开极慢单文件类数量过多按模块拆成多个 OOM用 Package 引用删除类后生成报错残留孤儿关系在浏览器树里删不在画布上删复制粘贴后 Code 重复粘贴时 Code 未自动加后缀批量选中改 Code或跑 Check Model反向工程后类名带下划线代码里用了下划线命名反向工程设置里配命名转换规则6.2 几个踩过的坑坑一在画布上整理布局忘了同步模型。有次我把十几个类拖到不同区域视觉上清爽了但包的归属完全没变生成代码时全在一个包里。后来养成习惯先在浏览器树里挪包再回画布摆位置。坑二反向工程直接覆盖。拿已有代码反向生成模型图省事选了覆盖结果手工补的注释和多重性全没了。正确姿势是新建一个模型做反向工程然后用Tools Compare/Merge Models比对差异人工决定哪些合并。比对功能需要 Repository 或者两个模型文件配置起来有点门槛但比人工肉眼比强太多。坑三多人同时改一个模型文件。PowerDesigner 的模型文件是单个二进制文件两个人同时改必然冲突后保存的覆盖前面的。没有 Repository 的团队我的建议是分模块拆文件每人负责自己的 OOM用包引用串起来或者约定同一时间只有一个人有编辑权其他人只读。坑四把类图当数据库设计图用。见过有团队直接在类图上标注表名、字段长度、索引然后一键转 PDM。转出来的表结构一塌糊涂因为类图的继承、组合、枚举在关系模型里没有直接对应。类图和物理数据模型是两个层次的东西中间需要一次人工映射决策这一步省不掉。最后分享一个我自己一直在用的整理节奏每次动模型之前先花十分钟只做一件事——把当前模型的类数量、关系数量、未命名对象数量数一遍记在模型文件的注释里。改完之后再数一遍。数字对不上说明有东西被误删或者漏改。这个方法很土但比任何检查工具都直接尤其适合接手别人模型的第一天。
阅读完成 · 觉得有帮助?
咨询建站