如您所知,类图是显示系统中不同类的属性、操作以及不同对象之间关系的图。

Class Diagram

 即使我已经使用它很长时间了; 每次使用的时候总是很混乱。 这篇文章就是为像我这样的人准备的; 对初学者也有帮助,这里我将用C++类示例解释类图。 

类表示

class Circle
{
private:
    double radius;
    Point center;
public:
    setRadius(double radius);
    setCenter(Point center);
    double getArea();
    double getCircumfrence();
};

上述类的类图如下所示。

类的不同可见性可以表示为

“+” Public
“-” Private
“#” Protected

不同的参数方向

“in”参数是一个输入参数。
“Inout” 该参数既可以输入也可以输出。
“Out” 该参数是一个输出参数。

类中不同类型的成员

1) 静态成员用下划线表示。
2) 纯虚函数用斜体表示。

类关系

在一个系统中,一个类可能与不同的类相关,以下是不同的关系。

  • 关联(Association)(知道一个)
  • 依赖(Dependency)(使用一个)
  • 聚合(Aggregation)(有一个)
  • 组合(Composition )(有一个)
  • 继承(Inheritance)(是一个)
  • 类模板(Class template)

关系中的不同多重性

“0..1” 没有实例,或一个实例(可选)
“1” 正好一个实例
“0..* or *” 零个或多个实例
“1..*” 一个或多个实例(至少一个)

关联(Association)

一个类知道另一个类; 一个类包含指向另一个类对象的指针或引用。

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

 1)单向关联

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

表示

C++ 示例

class X
{
public:
    Y *pY;
};

class Y
{
};

这里“X”类中的“Y *pY”没有任何生命周期依赖(组合),也没有暗示任何包含(聚合); 所以它是一个关联。 

2)双向关联

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

表示

C++ 示例

class X
{
public:
    Y* pY;
};

class Y
{
public:
    X* pX;
};

3)自身关联

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

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

表示

C++ 示例

class Object
{
public:
    int data;
    Object *next;
};

class ObjectList
{
public:
    Object *first;
    ObjectList();
    void insert(Object* obj);
    void print() const;
};

依赖(Dependency)

依赖用来表述一个类X“use”了另一个类Y。X可以是通过任何方式“use”类Y,如:

1)X的成员函数的返回值为Y;

2)X的成员函数使用Y作为函数参数;

3)X的成员函数的内部实现使用了Y;

表示

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

C++示例

class X
{
    ...
    Y    f0()     {…;  return y;      }

    void f1(Y y)  {…;  y.Foo();       }
    void f2(Y *y) {…;  y->Foo();      }
    void f3(Y &y) {…;  y.Foo();       }

    void f4()     {   Y y; y.Foo();  …}
    void f5()     {…; Y::StaticFoo(); }

    ...
};

聚合(Aggregation)

当一个类是其他类的集合或容器,但容器中包含的类对容器没有很强的生命周期依赖时,就会发生聚合——本质上,如果容器被销毁,它的内容不会被销毁。 您可能会混淆聚合和关联。关联与聚合的不同之处仅在于关联不表示任何包含关系。

表示

Window类包含其Shape的列表,Shape也可能被其他类共享;Shape的生命周期不取决于Window类。

C++示例

class Window
{
public:
    //...
private:
    vector<Shape> itsShapes;
};

组合(Composition )

组合是更强的聚合形式。 当一个类是其他类的集合或容器,但容器中包含的类对容器具有很强的生命周期依赖性时,可能会发生组合——本质上,如果容器被销毁,其内容也会被销毁。

表示

 C++ 示例

class Point
{
};

class Circle
{
private:
     ...
    Point center;
....
};
class X {
...
Y a; // 1; Composition
Y b[10]; // 0..10; Composition
};
 
class X {
X() { a = new Y[10]; }
~X(){ delete [] a; }
...
Y *a; // 0..10; Composition
};
 
class X {
...
vector<Y> a;    // if X contains vector, it is a composition;
};

class X {
...
vector<Y*> a;    // if X contains vector, and construction and destruction of Y* happen 
                 // inside X (in constructor/destructor) it is composition; otherwise 
                 // aggregation.
};

继承(Inheritance )/泛化(Generalization)

在继承关系中,一个类是从另一个类派生的。 这是两个类之间的“是一个”关系。

表示

这里Shape是一个抽象类,这就是它以斜体显示的原因。 Shape类的Draw()和Erase()方法是纯虚函数,所以也用斜体表示。

 C++示例

class Shape
{
public:
    virtual void Draw() = 0;
    virtual void Erase() = 0;
};

class Circle : public Shape
{
};

class Ellipse : public Shape
{
};

类模板

模板类是泛型类。C++、java、C#等语言都支持泛型编程。

表示

class_diagram_template

C++ 表示

template
class X {
...
...
...
};
X Y
...
X a;
...

template <typename Key, typename T>
calss MyMap
{
public:
    MyMap()
    {
    }

    virtual ~MyMap()
    {
    }
};

typedef MyMap<int, Person*> PersonMap;

参考链接:EA画UML图中如何创建类模板

// 简单的一个C++代码,实现数组的建立,以及给数组第一个元素赋初值和得到数组第一个元素的值
#include <iostream>

using namespace std;

template <typename T, int size>
class Array
{
private:
    T elements[size];

public:
    void addElement(T e)
    {
        elements[0] = e;
    }

    T getElement(int i)
    {
        return elements[i];
    }
};

using IntArray = Array<int, 20>;
using FloatArray = Array<float, 10>;
using CharArray = Array<char, 30>;

int main()
{
    IntArray array_int;
    array_int.addElement(3);
    cout << array_int.getElement(0) << endl;

    FloatArray array_float;
    array_float.addElement(3.5);
    cout << array_float.getElement(0) << endl;

    CharArray array_char;
    array_char.addElement('4');
    cout << array_char.getElement(0) << endl;

    return 0;
}

 运行结果:

 扩展阅读:UML—模板类实现

UML之类图

翻译原文:UML Class Diagram Explained With C++ samples

参考文章:C++ UML小结

UML学习:统一建模语言(UML)学习指南

visio绘制UML:

Visio画UML类图

visio中创建自定义的数据类型

用Visio做类图时,如何表示虚函数?内详

UML软件:免费在线流程图思维导图

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐