iOS设计模式 - UML类间关系精解

在正式讲设计模式之前, 介绍一下UML类图之间的关系还是很有必要的, 因为一些教程, 书籍, 包括我之后的文章, 都会大量使用类图, 去描述各个类之间的关系。这是一种非常直观, 简约的方式。

当然, 能力, 精力有限, 这里的UML的介绍也仅仅局限与几种常见的类间关系。

包括: 继承、实现、依赖、关联、聚合、组合



在次之前, 如果看不懂类图, 可以先看一下我之前写的一篇文章 :  详解八大UML类图符号的表示法


iOS - UML类间关系精解           by Colin丶

转载请注明出处:              http://blog.csdn.net/hitwhylz/article/details/40372781






一。继承


指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;

在 objective-c 中此类关系通过 : 明确标识,在设计时一般没有争议性;


UML类图: (用空心三角形 + 实现来表示。   方向从 子类指向父类)

uml


这里附带一下iOS类继承图:

关系




二。实现


指的是一个class类实现interface接口(可以是多个)的功能;实现是类与接口之间最常见的关系;

UML类图 (用空心三角形 + 虚线表示。 从类指向接口)

uml


三。依赖


可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、、临时性的、非常弱的,但是B类的变化会影响到A;比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖;比如人需要氧气进行新陈代谢, 那么人依赖氧气, 它们之间就是依赖关系。

表现在代码层面,为类B作为参数被类A在某个method方法中使用; 


UML类图 (用虚线箭头表示, 从依赖者[人]到被依赖对象[氧气], 注: 代码上表现为 氧气 作为 人 新陈代谢方法中的一个参数, 如: +新陈代谢(ino2 : 氧气))

ios


四。关联


他体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的、关联可以是单向、双向的;

表现在代码层面,为被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量;


UML类图 (用实现箭头表示 )

ios



五。聚合


聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与CPU、公司与员工的关系等;

表现在代码层面,和关联关系是一致的,只能从语义级别来区分;即 被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量; 


UML类图 (用空心的菱形 + 实线箭头表示)

关系


六。组合


组合也是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;比如你和你的大脑;

表现在代码层面,和关联关系是一致的,只能从语义级别来区分;即 被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量;


UML类图: (用实心的菱形 + 实线箭头表示 , 两端可以有数字。 比如 1 个人 有 1个大脑, 那两端就是1, 1)

ios 



对于继承、实现这两种关系没多少疑问,他们体现的是一种类与类、或者类与接口间的纵向关系;

其他的四者关系则体现的是类与类、或者类与接口间的引用、横向关系,是比较难区分的,有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;

但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖;

下面细致的做一下比较:



1.聚合与组合


(1)聚合与组合都是一种结合关系,只是额外具有整体-部分的意涵。

(2)部件的生命周期不同

聚合关系中,整件不会拥有部件的生命周期,所以整件删除时,部件不会被删除。再者,多个整件可以共享同一个部件。
组合关系中,整件拥有部件的生命周期,所以整件删除时,部件一定会跟着删除。而且,多个整件不可以同时间共享同一个部件。

(3)聚合关系是“has-a”关系,组合关系是“contains-a”关系。

2.关联和聚合


(1)表现在代码层面,和关联关系是一致的,只能从语义级别来区分。

(2)关联和聚合的区别主要在语义上,关联的两个对象之间一般是平等的,例如你是我的朋友,聚合则一般不是平等的。

(3)关联是一种结构化的关系,指一种对象和另一种对象有联系。

(4)关联和聚合是视问题域而定的,例如在关心汽车的领域里,轮胎是一定要组合在汽车类中的,因为它离开了汽车就没有意义了。但是在卖轮胎的店铺业务里,就算轮胎离开了汽车,它也是有意义的,这就可以用聚合了。

3.关联和依赖


(1)关联关系中,体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的。

(2)依赖关系中,可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A。

4.综合比较


这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系;但总的来说,后几种关系所表现的强弱程度依次为:

组合>聚合>关联>依赖;


下面简单举个例子, 区分聚合和组合的关系。

大雁喜欢热闹害怕孤独, 所以它们一直过着群居的生活, 这样就有了雁群 每一只大雁都有自己的雁群。每个雁群都有好多大雁, 大雁与雁群的这种关系就可以称之为聚合。

另外每只大雁都有两只翅膀, 大雁与雁翅的关系就叫做组合。 有此可见, 聚合的关系明显没有组合紧密, 大雁不会因为它们的群主将雁群解散而无法生存, 而雁翅就无法脱离大雁而单独生存——组合关系的类具有相同的生命周期。

聚合关系图:

关系

组合关系图:

uml

代码表现:

雁群类:

    public  class GooseGroup
    {
        public Goose goose;


        public GooseGroup(Goose goose)
        {
            this.goose = goose;
        }
    }

大雁类:

    public class Goose
    {
        public Wings wings;

        public Goose()
        {
            wings=new Wings();
        }
    }

聚合关系的类里含有另一个类作为参数
雁群类(GooseGroup)的构造函数中要用到大雁(Goose)作为参数把值传进来 大雁类(Goose)可以脱离雁群类而独立存在
组合关系的类里含有另一个类的实例化
大雁类(Goose)在实例化之前 一定要先实例化翅膀类(Wings) 两个类紧密耦合在一起 它们有相同的生命周期 翅膀类(Wings)不可以脱离大雁类(Goose)而独立存在
信息的封装性不同
在聚合关系中,客户端可以同时了解雁群类和大雁类,因为他们都是独立的
而在组合关系中,客户端只认识大雁类,根本就不知道翅膀类的存在,因为翅膀类被严密的封装在大雁类中。



大致就是这样了。 当然, 这只是UML的一部分。 如果有兴趣, 可以深入学习。


学习的路上, 与君共勉

关系 设计 模式 uml ios
您的回应...

相关话题

查看全部

也许你感兴趣

换一批

热门标签

更多