uml类关系(实现、继承,聚合、组合,依赖、关联)

drawio和EA是架构设计时经常使用的画图工具。

drawio学习门槛低,使用灵活,但是功能仅仅限于画图。

EA学习门槛高,但是功能更加的丰富:

①在画图方面,EA严格满足UML标准,EA中的图和类是关联的,如果修改了一个类的名字或者函数等,在引用这个类的图中也会自动修改

②EA还可以将架构设计时定义的类、接口等导出为代码

③EA可以导入已有的代码,生成类图

类似于表写代码,drawio类似于一种纯编辑器的代码,没有其它辅助的功能,EA类似于一个有丰富功能的IDE,可以有各种各样的提示,提供一种沉浸式的使用环境。

当讨论uml,最常见的使用场景就是类图。常用的类之间的关系包括实现、继承、聚合、组合、关联、依赖,而这六种关系中实现和继承关系类似,聚合和组合类似,依赖和关联类似。

本文中的类图使用EA来画。

1实现和继承

实现:

实现说的是类实现接口。在c++中,没有接口这个概念,抽象类可以看做接口。c++中的抽象类,是至少有一个函数是纯虚函数,这样的类不能实例化对象。如果以java语言的标准来定义c++中的接口和抽象类,那么接口中的函数都是纯虚函数,都没有自己的实现,抽象类中是至少有一个函数是纯虚函数,也可以有不是纯虚函数的函数。但是在很多时候,接口和抽象类的边界也没有这么清晰。接口可以看做是对类的行为的约束,值提供规则,不提供实现,就像很多行业中的标准制定者,只定义标准,不提供实现,比如网络通信协议标准、autosar标准等。

接口只定义标准,不提供实现,所以一个类对接口进行实现,就是实现的关系。当然,一个接口也可以继承一个接口。

如下代码,有一个接口类Shape,有两个实现类Rectangle和Circle。Rectancle和Circle是对Shape的实现。

cpp 复制代码
#include <iostream>
#include <cmath>
#include <stdexcept>

// Shape 接口类
class Shape {
public:
    virtual ~Shape() {} // 虚析构函数

    // 获取面积
    virtual double getArea() const = 0;

    // 获取周长
    virtual double getPerimeter() const = 0;

    // 打印形状信息
    virtual void printInfo() const {
        std::cout << "Area: " << getArea()
                  << ", Perimeter: " << getPerimeter() << std::endl;
    }
};

// 矩形类
class Rectangle : public Shape {
private:
    double width, height;

public:
    Rectangle(double w, double h) : width(w), height(h) {
        if (width <= 0 || height <= 0) {
            throw std::invalid_argument("Width and height must be positive");
        }
    }

    double getArea() const override {
        return width * height;
    }

    double getPerimeter() const override {
        return 2 * (width + height);
    }

    void printInfo() const override {
        std::cout << "Rectangle with width: " << width
                  << ", height: " << height << std::endl;
        Shape::printInfo();
    }
};

// 圆形类
class Circle : public Shape {
private:
    double radius;
    static constexpr double PI = 3.14159265358979323846;

public:
    Circle(double r) : radius(r) {
        if (radius <= 0) {
            throw std::invalid_argument("Radius must be positive");
        }
    }

    double getArea() const override {
        return PI * radius * radius;
    }

    double getPerimeter() const override {
        return 2 * PI * radius;
    }

    void printInfo() const override {
        std::cout << "Circle with radius: " << radius << std::endl;
        Shape::printInfo();
    }
};

int main() {
    try {
        // 创建各种形状
        Shape* shapes[] = {
            new Rectangle(4, 5),
            new Circle(3)
        };

        // 测试每个形状
        for (Shape* shape : shapes) {
            shape->printInfo();
            std::cout << std::endl;
            delete shape;
        }
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }
    return 0;
}

Rectangle和Circle堆Shape的实现关系,就可以表示为下图。实现关系用 三角形加虚线来表示。

继承:

实现是对一个没有实现的接口类进行实例化,进行实现,是一个从抽象到具体的过程。而继承是为了复用,继承说的是派生类和基类之间的关系。

还是以上边的图形类代码为例子,如果我们新增一个正方形的类,正方形是一个长和宽相等的特殊的矩形,所以正方形可以继承矩形。那么正方形类的代码如下:

cpp 复制代码
// 正方形类
class Square : public Rectangle {
public:
    Square(double length) : Rectangle{length,length} {
    }
};

实现是为了多态,继承是为了复用,可以看到,正方形类可以服用矩形类的函数和属性,正方形类只需要实现自己的构造函数即可。

继承关系用三角形加实现来表示。实现和继承的区别是,一个是虚线,一个是实线。

2聚合和组合

聚合和组合,两者均是表示整体与部分的关系,但是也是有区别的:

聚合:整体不存在了,部分还可以单独存在

比如汽车和轮胎、发送机、变速箱的关系,汽车是由轮胎、发动机、变速箱等聚合而成,但是轮胎、发动机、变速箱可以单独生产,在不有装车之前就可以存在,如果汽车要处理掉,这辆车可以拆卸,拆卸之后,汽车不存在了,汽车的零件还可以单独存在。

聚是一团火,散是满天星。聚和散都是存在的。

组合:整体不存在了,部分也就不存在了

比如公司和部门的关系,我们没有见过不依赖于公司而独立存在的部门,部门都是存在于公司内的,当公司倒闭,那么部门也就不存在了。

可以看到部分和整体之间的关系,组合的依赖更强。

下图是聚合的关系,聚合用空心菱形加实线表示。

下图是组合关系,组合用实心菱形加实现表示。

3依赖和关联

依赖关系也可以叫引用关系,也可以叫使用关系,说的是在一个对象中使用了另一个对象,那么就可以说前者依赖后者。比如程序员在工作中会用到电脑,那么就可以说两者的关系是依赖关系。

依赖关系如下图所示,依赖用箭头和虚线表示。

个人感觉关联和依赖之间的概念,并不是很清晰,没有很清晰的边界,有时候关联可以看做依赖,依赖也可以看做关联。 关联关系分单向关联、双向关联、自关联、多维关联。

单向关联,箭头加实线表示。

双向关联,实线两端均有箭头,也可以两端均没有箭头。

自关联,指向自身的实线表示,可以带箭头,也可以不带。

多维关联,表示多个对象之间的关联关系,可以用一个菱形来表示,当然也可以在多个对象之间两两关联来表示。

相关推荐
光头颜3 天前
UML之序列图事件时刻与轨迹
软件工程·uml
斗转星移34 天前
Ubuntu20.04 中使用vscode中编辑查看PlantUML
linux·vscode·uml·plantuml
未定义.2214 天前
电子削铅笔刀顺序图详解:从UML设计到PlantUML实现
java·软件工程·uml
aiden:)4 天前
UML 活动图深度解析:以在线购物系统为例
软件工程·软件构建·uml
未定义.2215 天前
UML-网络媒体教学系统顺序图深度解析
软件工程·uml
aiden:)5 天前
UML 状态图:以共享汽车系统状态图为例
汽车·软件工程·软件构建·uml
Yulong Huang7 天前
UML概览
uml
aiden:)8 天前
网上图书销售系统 UML 状态图解析:触发器事件、动作与监视条件
设计模式·软件工程·软件构建·uml
青木川崎8 天前
UML统一建模
uml