什么是UML?
UML(Unified Modeling Language,统一建模语言),是一种用于软件系统分析和设计的语言工具,用于帮助软件开发人员进行思考和记录思路的结果
UML本身是一套符号的规定,通过这些符号,来描述软件模型中各个元素之间的关系;比如类、接口、实现、泛化、依赖、组合、聚合等
UML图的目的
上面有介绍,UML是一种语音,语言的核心作用就是用来交流;不过他交流的方式并不是以传统意义上的说进行的,而是以图形加文字的方式进行;其最终的目的就是将真实的系统给抽象,然后以图文可视化的方式表达出来,使软件设计人员沟通更简明,进一步缩短了设计时间,减少开发成本。
这里的还有另外一个主要的目的,为了后续设计模式的过程中,结合UML类图,能更好的理解。
UML的分类
- 用例图
- 静态结构图
- 类图
- 对象图
- 包图
- 组件图
- 部署图
- 动态行为图
- 时序图
- 协作图
- 交互图
- 状态图
- 活动图
说明:
类图是描述类与类之间的关系,是UML图中最核心的部分;后续的设计模式讲解,也主要是通过类图来协助我们理解。那么这里也就主要讲解类图的部分了。
类图常用标识符
实体
简单的类图示例
代码语言:javascript复制public class User {
// 用户id
private Integer id;
// 用户名
public String name;
// 地址
protected String addr;
// 设置id
public void setId(Integer id) {
this.id = id;
}
// 获取用户名
public String getName() {
return name;
}
// 获取地址
public String getAddr() {
return addr;
}
}
类图
- 第一层:类名
最 、(private)#
中间为属性名称
右边为属性的类型
- 第三层:方法 结构和属性类似
关系
泛化(继承)
泛化关系又称之为继承关系(Generalization),用来描述类与类之间的父子关系
;父类又称之为基类,子类称之为派生类;
父类主要用来描述了一类事物的公有属性或行为
;
继承关系中,子类继承父类的所有功能,父类所具有的属性、方法,子类应该都有。子类中除了与父类一致的信息以外,还允许包括额外的信息。
例如:不管什么材质的门,都具备开门或关门的行为;否则,就不能称之为门了;所以他的材质和开关门的行为就可以定义为父类,其他所有的门都将继承自这个基类;
继承关系符
类图
代码实现
父类
代码语言:javascript复制public class Door {
// 材质
public String material;
// 开门
public void open(){
System.out.println(material "门打开了");
}
// 关门
public void close(){
System.out.println(material "门关上了");
}
}
木门
代码语言:javascript复制public class WoodenDoor extends Door{
public WoodenDoor(){
this.material = "木制";
}
}
玻璃门
代码语言:javascript复制public class GlassDoor extends Door{
public GlassDoor(){
this.material = "玻璃";
}
}
测试
代码语言:javascript复制public class Test {
public static void main(String[] args) {
Door woodenDoor = new WoodenDoor();
woodenDoor.open();
woodenDoor.close();
Door glassDoor = new GlassDoor();
glassDoor.open();
glassDoor.close();
}
}
运行结果
实现(Realization)
用来表达类与接口之间的关系;
接口是一个方法的集合,在实现关系中,实现类需要实现接口中定义的所有方法;
接口主要用来定义一类对象中,部分拥有的行为;
例如:所有的门都拥有开关门的行为,但是并不是所有的门都有门铃的行为,对于这种不是所有对象都有用的行为,我们就可以将其定义为接口;对象想拥有该行为,就实现对于的接口;
延续上一个示例,假定木门有门铃,玻璃门没有门铃,实现如下:
实现关系符
类图
代码示例
- 父类
public
class
Door
{
// 材质
public String material;
// 开门
public
void
open(){
System.out.println(material "门打开了");
}
// 关门
public
void
close(){
System.out.println(material "门关上了");
}
}
- 木门
public
class
WoodenDoor
extends
Door
implements
DoorBell{
public
WoodenDoor(){
this.material = "木制";
}
public
void
bell()
{
System.out.println(material "门的门铃响了:咚咚咚...");
}
}
- 测试代码
public
class
Test
{
public
static
void
main(String[] args)
{
Door woodenDoor = new WoodenDoor();
woodenDoor.open();
woodenDoor.close();
Door glassDoor = new GlassDoor();
glassDoor.open();
glassDoor.close();
// 判断有没有实现门铃的接口
if(woodenDoor instanceof DoorBell){
// 实现了 说明具备门铃的功能 然后就按门铃
((DoorBell) woodenDoor).bell();
}
// 同上
if(glassDoor instanceof DoorBell){
((DoorBell) glassDoor).bell();
}
}
}
测试结果
依赖关系(Dependency)
只要一个类中用到了其他类,那他们之间就存在依赖关系
例如:一个门(Door)的对象中包含了一个锁对象,要想开这个锁(Lock),就需要传入一个对应的钥匙(Key)对象。
依赖关系符
示例代码
- 锁
public
class
Lock
{
}
- 门
public
class
Door
{
Lock lock = new Lock();
public
void
open(Key key){
}
}
类图
如图可以看出,Door分别依赖了Lock和Key对象。
关联关系(Association)
关联关系实际上就是类与类之间的联系,他属于依赖关系的特例;
关联关系具有导航性,即单向关联
和双向关联
;
关联不仅存在一对一的关系,同样也存在一对多,多对多的关系;
例如:一个门对应一个门牌号,一个门牌号对应一个门;
关系符
类图
示例代码
- 门
public
class
Door
{
DoorPlate doorPlate = new DoorPlate();
}
类图
上图可以看出,在存在关联关系的同时,也存在着依赖关系,所以也就印证了上面说的,关联关系是依赖关系的一种特例。
聚合关系(Aggregation)
聚合关系表示一种整体与部分的关系;且这种整体与部分的关系是可以分开的,聚合属于关联关系的特例;所以他具有导航性和多重性。
例如:门和锁的关系,锁是门的一个组成部分,但是没有锁,对门的特性不会带来任何影响;也就是说,没有锁,门依然还是个门。
示例代码
- 锁
public
class
Lock
{
}
类图
组合(Composite)
组合是聚合的一种特例,只是他们关系是一种强关联关系,是一种不可分割的关系;
例如:门和门框的关系,门没有办法脱离门框独立存在于哪里;所以,有门的地方,必定会有个门框;
示例代码
- 门框
public
class
DoorFrame
{
}
类图
总结
到这里,常用到的UML实体及关系就说的差不多了,这并不是UML的全部,但是他是UML中最常用的部分;几乎可以解决日常工作、学习的90%以上的场景;
上面都是零碎的,结合上面所讲的细节,绘制了一个完整的包含6种关系的UML图,来协助更好的理解