UML-类图

【1】类图

类图: 面向对象系统建模中最常用、最重要的图,也是定义其它图的基础。

1.1 作用:主要是用来显示系统中的类、接口及它们之间静态结构和关系的一种静态模型。

1.2 基本组件:类名、属性(变量)、方法(函数)。

 1.3 代码中,类定义:

 1 class Student
 2 {
 3 public:
 4     void attendClass();
 5     static int getID();
 6     string getName();
 7 protected:
 8     void eat();
 9 private:
10     double cost();
11 
12 public:
13     int m_male;
14 protected:
15     int m_id;
16 private:
17     string m_address;
18     double m_score;
19 };

【2】泛化(Generalization)

2.1 表示is-a的关系。对象之间耦合度最大的一种关系,子类继承父类的所有细节。

2.2 在类图中使用带空心三角箭头的实线表示,箭头由子类指向父类。

简单理解记忆:1.箭头指向父:父亲具有唯一性,父与子是一对多的关系;2.实线,相对于下文接口实现的虚线而言)。

2.3 比如:Animal是基类,可以派生出类Cat、Dog、Pig等等

IDataUpdater是接口,可以派生出接口ISqlUpdater、IOracleDataUpdater等等

2.4 在代码中,即派生类继承于基类。示例如下:

 1 // 示例1:派生类继承于基类
 2 class Animal
 3 {
 4 public:
 5     void eat();
 6     void sleep();
 7 };
 8 
 9 class Cat : public Animal
10 {
11 };
12 
13 class Dog : public Animal
14 {
15 };
16 
17 class Pig : public Animal
18 {
19 };
20 
21 // 示例2:接口继承于接口
22 class IDataUpdater
23 {
24 public:
25     virtual void read() = 0;
26     virtual void write() = 0;
27 };
28 
29 class ISqlDataUpdater : public IDataUpdater
30 {
31 };
32 
33 class IOracleDataUpdater : public IDataUpdater
34 {
35 };

 【3】实现(Realization)

3.1 接口与实现(重写接口中的纯虚或虚方法)的关系。

3.2 在类图中使用带空心三角箭头的虚线表示,箭头从实现类指向接口。

简单理解记忆:1.箭头指向父,因为父亲具有唯一性,父与子是一对多的关系;2.虚,因为接口一般都是指纯虚函数)。

3.3 比如:IDataUpdater是数据更新接口,模块A的实现类为GSqlDataUpdater,模块B的实现类为GOracleDataUpdater。

3.4 在代码中,即类继承于接口。示例如下:

 1 // 示例:类继承于接口
 2 class IDataUpdater
 3 {
 4 public:
 5     virtual void read() = 0;
 6     virtual void write() = 0;
 7 };
 8 
 9 class GSqlDataUpdater : public IDataUpdater
10 {
11 };
12 
13 class GOracleDataUpdater : public IDataUpdater
14 {
15 };

【4】关联(Association)

4.1 关联分为一般、聚合和组合关联。此节主要指一般关联。

4.2 一般关联指对象之间一种引用关系,比如:客户类与订单类之间的双向关联关系;客户与联系地址之间的单向关联关系。

4.3 在类图中使用带箭头的实线表示,箭头从使用类指向被关联的类。

4.4 关联双方关系一般是平等的。关联可以是单向或双向的。

4.5 在代码中,即类的成员对象:

一种:被关联类B以类成员的形式存在于关联类A中。

另一种:关联类A引用了一个类型为被关联类B的全局对象。

 1 class Address
 2 {
 3 public:
 4     string getAddress();
 5 };
 6 
 7 class Order
 8 {
 9 private:
10     Customer m_owner;            // 即一个订单关联着一个客户(双向关联)
11 };
12 
13 class Customer
14 {
15 public:
16     void setAddress(Address& newAddress)
17     {
18         m_address = newAddress.getAddress(); // 客户类只是知道有Address这个类
19     }
20 
21 private:
22     Order& m_orders[10];     // 即一个客户关联着10个订单
23     string& m_address;       // 即一个客户关联着1个住址
24 };

【5】聚合(Aggieregation)

5.1 较强于一般关联,表示has-a的关系,是一种不稳定的包含关系。

5.2 整体与局部的关系,且没有了整体,局部也可单独存在。双方具有各自的生命周期。

5.3 在类图使用空心的菱形表示,菱形从局部指向整体。

5.4 比如:公司与员工的关系,公司包含员工,如果公司倒闭,员工依然可以换公司。

或者汽车和轮胎、引擎的关系。

5.5 在代码中,即类的成员对象。示例如下:

 1 // 示例1:一个公司聚合100个员工
 2 class Employee;
 3 class Company
 4 {
 5 private:
 6     Employee m_employees[100];
 7 };
 8 
 9 // 示例2:一辆汽车聚合一个引擎和4个轮胎
10 class Tyre;
11 class Engine;
12 class Car
13 {
14 private:
15     Tyre m_tyre[4];
16     Engine m_engine;
17 };

【6】组合(Composition)

6.1 表示contains-a的关系,是一种强烈的包含关系,一种更强的聚合关系。

6.2 组合关系类具有相同的生命周期。组合类负责被组合类的生命周期,即部分不能脱离整体而独立存在。

6.3 在类图使用实心的菱形表示,菱形从局部指向整体。

6.4 比如:公司和部门的关系,没有了公司,部门也不能存在了;对于人而言,头和嘴之间的关系。

6.5 在代码中,即类的成员对象。示例如下:

 1 // 示例1:头由嘴组合
 2 class Mouth;
 3 class Head
 4 {
 5 private:
 6     Mouth m_mouth;
 7 };
 8 
 9 // 示例2:公司由部门组合
10 class Department;
11 class Company
12 {
13 public:
14     Company()
15     {
16         m_pDevelopment = new Department();
17         m_pTest = new Department();
18     }
19     ~Company()
20     {
21         delete m_pDevelopment;
22         delete m_pTest;
23     }
24 
25 private:
26     Department *m_pDevelopment;
27     Department *m_pTest;
28 };

【7】依赖(Dependency)

7.1 对象之间最弱的一种关联方式,是临时性、偶然性的关联。

7.2 在类图使用带箭头的虚线表示,箭头从使用类指向被依赖的类。

7.3 比如:人类需要依赖食物类;人类分解食物为能量,需要依赖能量类。

或某人要去某地,需要开一辆车,此时人与车之间的关系就是依赖。

7.4 代码中,即由局部变量、函数参数、返回值建立的对于其他对象的调用关系。一个类调用被依赖类中的某些方法而得以完成这个类的一些职责。

 1 // 局部对象、静态方法、方法参数
 2 class Energy;
 3 class Food
 4 {
 5 public:
 6     static Energy decompose() {};
 7 };
 8 class Human
 9 {
10 public:
11     Energy decompose()
12     {
13         Food *pFood = new Food();
14         pFood->decompose();
15     }
16     void eat(Food food)
17     {
18         Energy energy = food.decompose();
19     }
20 };

【8】总结

8.1 聚合与组合的区别

聚合与组合是有很大区别的,这个区别不是在形式上,而是在本质上:

实际代码中,组合方式一般这样表达:A类的构造函数里创建B类的对象。

也就是说,当A类的一个对象产生时,B类的对象随之产生,当A类的这个对象消亡时,它所包含的B类的对象也随之消亡。

实际代码中,聚合方式一般则是这样表达:

A类的对象在创建时不会立即创建B类的对象,而是等待一个外界的对象传给它,传给它的这个对象不是由A类创建的。

再通俗一点,在现实生活中:

人和手、脚是组合关系,因为当人死亡后人的手、脚也就不复存在了。而人和他的电脑、手机等是聚合关系。

8.2 关系强弱

聚合、关联、组合是对象之间的三种关系。

从某种意义上说,继承(泛化、实现)是一种类的纵向关系,而聚合、关联、组合是对象的横向关系。

关系由强至弱顺序:泛化 ≈ 实现 > 组合 > 聚合 > 关联 > 依赖

8.3 通俗理解

人和人的心脏之间是composition(组合)关系(心脏只属于自己)

人和人的手机之间是aggregation(聚合)关系(手机可能属于别人)

人和人的朋友之间是association(关联)关系(知道自己有个朋友,偶尔坐一起扯扯淡或借点钱)

 

Good Good Study,Day Day Up.

顺序 选择 循环 总结

posted @ 2017-09-11 14:58  kaizenly  阅读(2298)  评论(2编辑  收藏  举报
打赏