Chinaunix首页 | 论坛 | 博客
  • 博客访问: 238238
  • 博文数量: 16
  • 博客积分: 345
  • 博客等级: 一等列兵
  • 技术积分: 611
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-19 00:16
文章分类

全部博文(16)

文章存档

2013年(2)

2012年(14)

我的朋友

分类: C/C++

2012-12-21 21:57:48

在UML类图中,类与类之间有几种常见关系:依赖、关联、聚合、组合、泛化。

1、依赖(Dependency)

依赖是一种很有用的关系,它用来表述一个类A“use”了另一个类B。A可以是通过任何方式“use”类B,如:

1)A的成员函数的返回值为B;

2)A的成员函数使用B作为函数参数;

3)A的成员函数的内部实现使用了B;

依赖关系通常使用虚线箭头“---->”表示,箭头指向被“use”的类。

image

在C++代码中,依赖关系是这样对应的:

点击(此处)折叠或打开

  1. class A
  2. { 
  3.     public: 
  4. B returns_a_B();
  5. void has_a_B_argument(B);
  6. void has_a_B_in_its_implementation();
  7. };
  8. A::void has_a_B_in_its_implementation(){ B b; }

2、关联(Association)

关联可以表述成一个类“知道”另一个类。如何“知道”呢?在C++中,类A“知道”类B一般是通过指针实现的(也可以使用引用或者值),即类A有一个成员变量是指向B的指针(或者引用、值)。

关联可以分为双向关联、单向关联、自身关联。

1)双向关联

双向关联A-B:双方都“知道”对方,都可以调用对方的公共属性和方法。

image

对应的C++代码为:

点击(此处)折叠或打开

  1. class A {
  2.     public:
  3.         B* pB;
  4. };
  5. class B {
  6.     public:
  7.         A* pA;
  8. };

2)单向关联

单向关联A->B:表示A“知道”B,A可以调用B的公共属性和方法。没有生命周期的依赖。

image

对应的C++代码为:

点击(此处)折叠或打开

  1. class A {
  2.     public:
  3.         B* pB;
  4. };
  5. class B {
  6. };

3)自身关联

自身关联:自己引用自己,这个在链表中非常常见。

可以看到,上面的Object类,就是一个自身关联的应用,它有一个自己指向自己的指针,用来实现链表。

image

对应的C++代码为: 

点击(此处)折叠或打开

  1. class Object {
  2.     public:
  3.         int data;
  4.         Object* next;
  5. };
  6. class ObjectList {
  7.     public:
  8.         Object* first;
  9.         ObjectList();
  10.         void insert(Object* obj);
  11.         void print() const;
  12. };

3、聚合(Aggregation)和组合(Composition)

聚合和组合都是用在表述整体-部分关系的时候,二者只是在生命周期问题上有差异。

1)聚合通常可以理解成“has a”关系。如果类A聚合类B,那么类A“has a”类B,同时,在A的生命周期结束后类B必须依然存在或者有意义。比如房间有一张桌子,那么房间和桌子的关系就是聚合:即使房间没有了,那张桌子还是存在的,桌子是可以脱离房间而存在的。

image

对应的C++代码: 

点击(此处)折叠或打开

  1. class Table {

  2. };
  3. class Room {
  4.     public:
  5.     Table aTable;
  6. };

2)组合通常可以理解为“is a part of”。和聚合不同的是,如果类A组合类B,那么当A生命周期结束后,类B也随之结束,也就是说B不能脱离类A而存在。就如同鸟都有两只翅膀一样,当鸟消失了,翅膀也随之不存在了。

image

对应的C++代码:

点击(此处)折叠或打开

  1. class Wing {

  2. };
  3. class Bird{
  4.     public:
  5.         Wing leftWing;
  6.         Wing rightWing;
  7. };

可以发现,如果单纯从C++代码来看,聚合关系和组合关系没有什么不同,要区分聚合和组合,只能从语义分析。

补充:

组合关系还有另一层含义:“is a”。不过这种含义,仅仅用来角色方面,即“is a”角色。比如一个人,是丈夫角色。那也可以看做组合;手机可以看做“Camera”、“Music Player”等。

image

从上图我们可以看出,Battery和Smart Phone是聚合关系,因为电池是手机的一部分,但是电池可以脱离手机而存在。而IMEI Number和Smart Phone是组合关系,一般情况下一个Smart Phone只有一个IMEI Number,手机消失后,IMEI跟着消失。而我们知道现在的手机可以拍照、上网、播放音乐,因此手机可以扮演相机、web冲浪、音乐播放器的角色,所以Smart phone和Camera、Web Browser、Music Player是组合的关系。

4、泛化(Realization)

泛化关系也被常用作继承(inherit)关系,是用来表述“Is-a”这种关系的,比如Car和Police-Car的关系,Police-Car “is a” Car。

image

对应的C++代码为: 

点击(此处)折叠或打开

  1. class Car {

  2. };

  3. class Police_Car{

  4. };

阅读(2093) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~