UML类图精炼及其最佳实践

田海立@CSDN 2020-10-08

UML(Unified Modeling Language)的各种图中类图(Class Diagram)是基础,描述一个系统可以从不同视角去看,这些不同视角的图聚合在一起,才能比较完整地阐述系统。本文描述类图的基本概念——各种类元和它们之间的关系,并结合实际工作经验探讨了描述类图时的最佳实践。

UML中的类图描述的是什么,最基本的问题也才最关键,有些时候真的可能是做了很长时间的事,基本的概念都还没搞清楚。类图描述的类(接口)的组成和行为、以及这些类组合在一起后它们之间的关系。这是一种静态关系,所以一般的著作中会把它归类到静态图里。

一、UML类图

1.1 类图中的类/接口

1) 类

类是有着相同结构、行为和关系的一组对象的抽象,在几乎所有的面向对象语言中都有实现,概念也大同小异。UML类图中也有同样的概念。

类用矩形来表示,包含类名/属性/操作,可能还有其他修饰符。

类名:根据类的属性,可能还会有差异。比如用斜体表示抽象类;加下划线表示静态类。

属性:是类的成员,用 <可见性><属性名>: <类型> = <初始值>来表示

  •     <可见性>:一般+表示public;-表示private;#表示protected,也有些工具用对应的图标来表示
  •     <属性名>:为属性取个名字
  •     <类型>:可以是另外一个自定义的类,也可以是基本类型;
  •     <初始值>:属性的初始赋值

  一般,属性是private的可见性,为了能外部获取和设置,分别还要写setter和getter操作。

  另外,静态(类)属性用下划线表示。

操作:也是类的成员,用 <可见性><操作名>(参数名: <参数类型>): <返回值类型>来表示

  •     <可见性>:一般+表示public;-表示private;#表示protected,也有些工具用对应的图标来表示
  •     <操作名>:为属性取个名字
  •     <参数类型>/<返回值类型>:可以是另外一个自定义的类,也可以是基本类型;

  一般,操作是public的可见性,为了父子类之间的重写用protected。

  另外,抽象的操作也用斜体表示;静态(类)操作用下划线表示。

2) 接口

接口可以认做是一种特殊的类,只包含操作不包含对象属性。有些面向对象语言(比如Java)里有这个概念,也有些语言(比如c++)根本没有特别定义这种类型。

注:

  1. 接口里也可以有接口(类)属性的,属于全体的,不是某一个对象的,常用来定义一些常量。
  2. 不同UML工具表达的接口的形状可能也不一样,一般的只是在类的基础上加上《interface》的原型。

1.2 类图中的关系

类图中的关系有关联(聚合、组合)、泛化、实现、依赖等。

1) 关联(Association)

两个类之间连接起来的关系,有方向性、多重性、可见性。

  • 方向性:一个类A中访问另一个类B的对象,是A指向了另一个类B的关联。如果B也指向了A,那它们之间就是双向的。
  • 多重性:一个类关联到另一个类,可能是其中多个对象的关联,所以有1、0...*、1...*或*等多重性。

聚合(Aggregation)是整体和部分的关联关系,用空心菱形连接整体

组合(Composition)是更强关系的关联,不能独立存在,即如果整体不存在部分也会消失。用实心菱形连接整体。

2)泛化(Generalization)

泛化是UML里的概念,对应面向对象的概念里就是继承。用实线连接一个三角箭头表示,子类指向父类。

3)实现(Realization)

实现用虚线连接一个三角箭头表示,由实现类指向接口。

4)依赖(Dependency)

依赖是类图关系中关系最疏远的一种,应用范围也最广,为了描述准确,可以加上具体依赖关系的描述:access、call、import、use等。

注意:关联关系是所有这些关系中唯一的描述其他类的对象之间的关系,其他关系描述的是类之间的关系。

上面简要讲述了类图中的元素以及它们之间的关系。笔者很庆幸理论学习到的基础在毕业之初就在做嵌入式工作中实际应用到了UML,虽然系统不是面向对象的语言来实现,但处处体现的是面向对象的思想和以及如何来表达和呈现。从事嵌入式或移动端工作的大众用UML应该是Android兴起面向对象真正实用之后。回过头来看,实际使用16年之久了也从没丢弃过,这里总结一下实际应用时的最佳实践,与诸君探讨。

二、最佳实践

1. 以交流以消除二义性为目的

UML从字面理解它还是种语言,只是这是用来建模的,所以,在你的团队中如果有理解不一致的地方,达成一致最重要。也因了它被OMG纳为了标准,更能消除方言,消除表达的二义性。

比如:

  • 可见性用图标还是符号表示;
  • 接口怎么表示;
  • 类之间的关联关系用什么来表达:不同阶段(分析/设计/实现)精化到不同层次,个人觉得能到聚合和组合关系的,别停留在关联关系上。

而不同系统不同团队之间,如果不是与标准向违背的前提下别试图非要统一化别人。说这“不与标准向违背”的意思是,也有多少人真的是不求甚解,还大庭广众,大言不惭连基本概念都没有的整天把顺序图说成流程图。

2. 呈现的内容层次要一致、篇幅要恰当

类图上呈现的当然应该是第一部分讲述的内容,当然为了说明也可以有注释等内容。这里要说的一张类图要呈现哪些内容:多少类/接口;多少方法/属性。

呈现多少,这里有些基本的前提:

  • 把要描述的内容讲述清楚:比如想要呈现整体架构图,那就着重描述各种关键类,以及它们之间的关联,而类具体的属性和操作以及内部实现的内容就不要呈现了。而如果要描述一个类的实现,那另一张图就要呈现这个类的属性/操作以及内部的实现细节了。
  • 一张图上表达的层次要一致:不能一个类表达的外部功能,而另一个表达的很细节,是内部的实现细节,而这张图会重点不突出,反而不如拆开表达。
  • 最好是一张A4纸可以打印的下的内容:这样清晰明了,读者也容易抓住全图。过多的表达可以拆分到另外的图,“分而治之”。

3. 图在开发的不同阶段要呈现不同内容

在系统开发过程中,不同阶段呈现的内容,读者所关心的内容都不相同。这里比如关联关系,在需求阶段简单标注关联就好,不用关注方向性、多重性等;但到了设计阶段,却是要必须明确的内容了。

4. 与其他图的关系:静态视图vs动态视图

UML图中的各种图都不是孤立存在的,它们之间都有关联,把这么图综合起来,才描述了系统的全貌。

类图是静态视图,类的实例化是对象,某一时刻的快照(snapshot)也就是对象图,复杂系统的关键场景,对象图也很关键,帮助建立系统模型的全景。

而类图中的类的实例(也就是对象)组合在一起按照时间顺序的执行过程也就是顺序图。顺序图描述了对象之间按时间交互完成一个个场景,不同的场景可能需要用不同的顺序图来表达,一般的需要包含:典型场景、异常场景、边界处理场景等。

5. UML工具

工欲善其事,必先利其器。用UML来表达,当然需要用一套专业的工具。

这里也没什么特别推荐,公司已经有采购,当然Rose了。

不推荐vision,虽然vision里也号称可以画UML图,那体验完全不是UML,跟你用画图板差不多。除非公司有强制要求,或获取不到别的工具。

另外,还有些免费的或者有免费体验版的也很不错,说到底你用的只是体现UML概念的基本功能,没基本功能也不能号称支持UML x.y了。这些有starUML、VisualParadigm社区版等。

猜你喜欢

转载自blog.csdn.net/thl789/article/details/108959644
今日推荐