1

说来惭愧,写了很长时间的代码了,直到现在才开始反思什么是面向对象,反思类和类之间的关系。

1、什么是uml类图

统一建模语言(英语United Modeling Language ,缩写uml)。
主要包含三种类型的模型:功能模型、对象模型、动态模型。而我们所使用的的uml类图,就是对象模型中的一种。[(维基百科详细解释)] 链接描述
(ps:有很多uml建模工具,我们这里使用powerdesigner)

2、类(接口)之间的关系

从比较宽泛的范围来讲,其实类图之间的关系只有三种 继承、实现、关联。

继承和实现其实是从纵向的角度而言的,例如:A类继承了B类, A接口实现了B接口;

关联是横向角度而言的,依据类与类之间的依赖关系从弱到强可以划分为 依赖 < 关联 < 聚合 < 组合

我们一般对纵向关系的继承和实现不太陌生,而对横向关系的关联就不甚了解,其实我们很多地方都用到了关联,只是我们没有注意罢了。

3、举例说明类(接口之间的关系)

1、纵向关系 - 继承

一般用于父子关系,一般也没有什么争议。判断是否具有父子关系,可以基于里氏替换原则,父子类之间是否存在is-a的关系,如:例子中的 鸟 是 一种动物;
在uml中,我们使用空心三角形 + 实线来表示

图片描述

2、纵向关系 - 实现

一般用于类对接口的实现,在例子中 大雁实现了飞翔接口
在uml中,我们使用空心三角形 + 虚线线来表示
图片描述


相对于纵向关系而言,横向关系似乎没有那么清楚,究竟是依赖,关联,聚合,组合中的哪一种,其实很大程度上取决于语意,我们更多的时候需要人为的去进行判断,往往会带有主观的想法。但是,我们可以遵循一些基本的原则来区分

  • 类双方的地位可能有所不同

  • 依赖程度不同

  • 在代码层面的表现形式不同

  • uml类图的表现形式不同


3、横向关系 - 依赖

就双方的地位而言,依赖的双方的地位往往是独立的、平等的;


就依赖程度而言,依赖的双方往往是偶尔的、临时性的、不频繁的;例如需要借用一条船,此时人与船之间的关系就是依赖,我么可以认为Person 依赖 Boat


就代码层面的表现形式而言,往往是局部的变量,常常会以下面三种形式出现:
(1)类B以参数的形式传入类A的方法。
(2)类B以局部变量的形式存在于类A的方法中。
(3)类A调用类B的静态方法。


在uml类图中,我们使用虚线 + 箭头的形式表示依赖关系


例子:
图片描述

4、横向关系 - 关联

就双方的地位而言,依赖的双方的地位往往是独立的、平等的;如公司A和公司B


就依赖程度而言,关联的双方往往比依赖往往是长期的、稳定的、频繁的;例如CompanyAlass和CompanyBlass属于长期合作的关系,彼此需要双方提供的服务


就代码层面的表现形式而言,关联往往以全局属性的形式存在

如果CompanyA 和 CompanyB同时以全局属性的形式在双方的类定义中出现,我们认为,这种属于双向关联。

如果CompanyA 或 CompanyB 其中一方以全局属性的形式在另一方的类定义中出现,我们认为,这种属于单项关联


在uml类图中,我们使用实线 + 箭头的形式表示依赖关系


例子:
图片描述

5、横向关系 - 聚合

就双方的地位而言,聚合的双方的地位不是平等的,是整体和部分之间的关系。整体和部分都有自己的生命周期,一方的消失另外一方不会跟着消失。


就依赖程度而言,关联的双方往往比依赖往往是长期的、稳定的、频繁的,这种关系比关联更强,以至于在形式上出现了整体和部分之间的关系, 例如 CompanyA 拥有员工 EmployeeA


就代码层面的表现形式而言请直接参考关联即可


在uml类图中,我们使用实线 + 空心菱形进行表示


例子:
图片描述

6、横向关系 - 聚合

就双方的地位而言,聚合的双方的地位不是平等的,是整体和部分之间的关系。部分的生命周期取决于整体,部分随着整体的消失而消失

区分是聚合还是组合的核心点是在生命周期。如CompanyA 拥有员工 EmployeeA,
和拥有DepartmentA。有一天可能CompanyA公司倒闭了,但是,EmployeeA员工,不会因为公司的倒闭而消失,他会加入另外一家公司CompanyB。而DepartmentA则不同,公司倒闭后,部门自然就不存在了。所以从依赖关系上进行区分可以知道,前者是聚合,后者是组合。


就依赖程度而言,关联的双方往往比依赖往往是长期的、稳定的、频繁的,这种关系比聚合更强,以至于在形式上出现了整体和部分之间的关系,并且部分的生命周期随着整体消失而消失 例如 CompanyA 拥有部门 DeparmentAs, 如果有一天CompanyA 不存在了,那么DeparmentAs这个部门自然也不存在了


就代码层面的表现形式而言请直接参考关联即可


在uml类图中,我们使用实线 + 实心菱形进行表示


例子:
图片描述

区分是聚合还是组合的核心点是在生命周期。

如CompanyA 拥有员工 EmployeeA,和拥有DepartmentA。
有一天可能CompanyA公司倒闭了,EmployeeA员工,不会因为公司的倒闭而消失,他会加入另外一家公司CompanyB。

而DepartmentA则不同,公司倒闭后,部门自然就不存在了。
所以从依赖关系上进行区分可以知道,前者是聚合,后者是组合。

4、参考资料

《大话设计模式》
http://www.cnblogs.com/olvo/a...
http://www.cnblogs.com/linjiq...

ps:以上是自己的一些理解,如有问题请及时指出


maweibinguo
783 声望36 粉丝

后端开发工程师一枚, keep moving