一、前言
很多博客里面都会涉及到UML图,主要快速反映出程序的设计结构,类与类之间的依赖关系等,所以这个技能还是需要掌握的。以后自己也要多画一些,这样熟能生巧,便于掌握。
什么是UML
Unified Modeling Language (UML)又称统一建模语言或标准建模语言,是始于1997年一个OMG标准,它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。
UML规范用来描述建模的概念有,类(对象的)、对象、关联、职责、行为、接口、用例、包、顺序、协作,以及状态。
绘制UML工具
- 网页版:https://www.processon.com/
- 软件版:PowerDesigner(个人使用)
补充知识——类间关系
- 纵向关系:继承
-
横向关系:依赖(Dependency)、关联(Association)、聚合(Aggregation)和组合(Composition)
-
依赖:" ... uses a ...",就是某个对象的功能依赖于另外的某个对象,而被依赖的对象只是作为一种工具在使用,而并不持有对它的引用。
public class Human{ public void breath(){ Air freshAir = new Air(); freshAir.releasePower(); } public static void main(String[] args){ Human me = new Human(); while(true) { me.breath(); } } } public class Air{ public void releasePower(){ //do sth. } }
-
关联:" ... has a ...",某个对象会长期的持有另一个对象的引用,而二者的关联往往也是相互的。关联的两个对象彼此间没有任何强制性的约束,只要二者同意,可以随时解除关系或是进行关联,它们在生命期问题上没有任何约定。被关联的对象还可以再被别的对象关联,所以关联是可以共享的。
public class Human{ private ArrayList friends = new ArrayList(); public void makeFriend(Human human){ friends.add(human); } public static void main(String[] args){ Human me = new Human(); while(true) me.makeFriend(mySchool.getStudent()); } }
-
聚合:" ... owns a ...",聚合是强版本的关联,它暗含着一种所属关系以及生命期关系。被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系。
public class Human{ private Home myHome; public void goHome(){ //在回家的路上 myHome.openDoor(); //看电视 } public static void main(String[] args){ Human me = new Human(); while(true){ //上学 //吃饭 me.goHome(); } } }
-
组合:" ... is a part of ...",组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。被包含的对象还可以再被别的对象关联,所以被包含对象是可以共享的,然而绝不存在两个包含对象对同一个被包含对象的共享。组合关系就是整体与部分的关系,部分属于整体,整体不存在,部分一定不存在,然而部分不存在整体是可以存在的,说的更明确一些就是部分必须创生于整体创生之后,而销毁于整体销毁之前。部分在这个生命期内可以被其它对象关联甚至聚合,但有一点必须注意,一旦部分所属于的整体销毁了,那么与之关联的对象中的引用就会成为空引用,这一点可以利用程序来保障。
public class Human{ private Heart myHeart = new Heart(); public static void main(String[] args){ Human me = new Human(); while(true) { myHeart.beat(); } } }
-
注:依赖常常是局部变量、形参或者对静态方法的调用,其他三个常常是成员变量。
二、计算器程序的UML图
关于上一篇文章中实现的计算器程序,最终的UML图可以表示为:
需要注意连线箭头的区别。图中一个方框代表一个类,第一行代表类的名称,第二行表示类包含的属性,第三行代表类中包含的方法。在属性和方法前有一个“+”修饰,表示public属性,而“-”代表private属性,“#”代表protected属性。
三、UML图的绘制
-
总体UML图
动物需要氧气和水,鸟类也是一种动物,它还有翅膀。大雁、鸭子都属于鸟类,多个大雁形成雁群,而企鹅的生存和气候相关。大雁区别于其他俩种,它能够飞翔,而唐老鸭是一种特殊的鸭子,毕竟它可以说话。
-
依赖关系
动物类包含有生命的public属性和新陈代谢和繁殖的public方法。如果类名用斜体表示,则该类为抽象类。动物的生存需要氧气、水等,所以这是一个依赖关系,用虚线箭头表示即可。public class Animal{ public void metaBolism(Oxygen oxygen, Water water){ ... } }
-
组合关系
组合关系是一种强的“拥有”关系,体现了严格的部分与整体的关系,部分和整体的生命周期一样。鸟和翅膀就是一个组合关系,组合关系用实心菱形+实线箭头来表示。同时连线俩端还有数字来表示基数,表明一个类可以拥有几个实例。这里,显然一个鸟有俩个翅膀。如果一个类可以拥有无数个实例,则可以用n来表示。下面的关联关系、聚合关系也是可以有基数的。public class Bird{ private Wing wing; public Bird(){ wing = new Wing(); } }
-
聚合关系
大雁是群居动物,每只大雁都属于一个雁群,一个雁群可以有多个大雁,所以这是一个聚合关系。聚合表示一个弱拥有关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分。聚合关系用空心菱形+实线箭头来表示。在雁群类中,有大雁数组对象arrayWideGoose。public class WideGooseAggregate{ private WideGoose[] arrayWideGoose; }
-
关联关系
企鹅是特别的鸟,会游不会飞。更重要的是,它得生活在特定的气候条件下,它需要知道气候的变化情况,需要了解气候规律。当一个类“知道”另一个类的时候,可以用关联关系表示。关联关系用实线箭头表示。public class Penguin extends Animal{ private Climate climate; }
-
继承关系
继承关系应该非常容易理解,不多BB,关系用空心三角形+实线表示。public class Bird extends Animal{ ... }
-
实现接口
因为大雁、企鹅和鸭中只有大雁能在高空飞翔,所以实现了飞翔接口。接口图的表示与类不同,接口在第一行有<<interface>>显示,第二行是接口方法。书中还举例了棒棒糖表示法表示接口,可自行查看。实现接口用空心三角形+虚线表示。public interface IFly{ ... } public interface ILanguage{ ... }