UML(统一建模语言)

news2024/11/24 5:00:45

面向对象设计主要就是使用UML的类图,类图用于描述系统中所包含的类以及它们之间的相互关系,帮助人们简化对系统的理解,它是系统分析和设计阶段的重要产物,也是系统编码和测试的重要模型依据。

画图软件:ProcessOn思维导图流程图-在线画思维导图流程图_在线作图实时协作

类的UML画法

类(class / struct)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。

在系统中,每个类都具有一定的职责,职责指的是类要完成什么样子的功能,要承担什么样子的义务。一个类可以有多种职责,但是设计得好的类一般只有一种职责。

class Hunter
{
public:
    int m_age = 32;
    static int m_times;
    string getName()
    {
        return m_name;
    }

    void setName(string name)
    {
        m_name = name;
    }

    void goHunting()
    {
        aiming();
        shoot();
    }
    static void saySorry()
    {
        string count = to_string(m_times);
        cout << "Say sorry to every animal " + count + " times!" << endl;
    }

protected:
    string m_name = "Jack";
    void aiming()
    {
        cout << "使用" + m_gunName + "瞄准猎物..." << endl;
    }

private:
    string m_gunName = "AK-47";
    void shoot()
    {
        cout << "使用" + m_gunName + "射击猎物..." << endl;
    }
};
int Hunter::m_times = 3;

类图分为上中下三部分:上层是类名;中层是属性(类的成员变量),下次是方法(类的成员函数) 

  •  访问权限:+ 代表 public 、 # 代表 protected 、 - 表示 private
  • _(下划线) 表示static
  • 属性:【可见性】【属性名称】:【类型】={缺省值,可选}
  • 方法:【可见性】【方法名称】(【参数名:参数类型,......】):【返回值】

如果我们定义的类是一个抽象类(类中有纯虚函数),在画UML类图的时候,类名和虚函数需要使用斜体显示,如果是纯虚函数则需要在最后函数指定 = 0

继承关系

继承也叫作泛化(Generalization),用于描述父子类之间的关系,父类又称为基类或者超类,子类又称作派生类。在UML中,泛化关系用带空心三角形的实线来表示。(从子类指向父类)

关于继承关系一共有两种:普通继承关系和抽象继承关系,但是不论哪一种表示继承关系的线的样式是不变的。

class Bird
{
public:
    string getName()
    {
        return m_name;
    }

    void setName(string name)
    {
        m_name = name;
    }

    virtual void fly() {}
    virtual void eat() {}
protected:
    string m_sex;
    string m_name;
};

class Cuckoo : public Bird
{
public:
    void fly() override
    {
        cout << "我拍打翅膀飞行..." << endl;
    }

    void eat() override
    {
        cout << "我喜欢吃肉肉的小虫子..." << endl;
    }
};

class Eagle : public Bird
{
public:
    void fly() override
    {
        cout << "我展翅翱翔..." << endl;
    }

    void eat() override
    {
        cout << "我喜欢吃小动物..." << endl;
    }
};

父类Bird中的fly()和eat()是虚函数,它有两个子类Cuckoo和Eagle在这两个子类中重写了父类的虚函数,在使用带空心三角的实现表示继承关系的时候,有空心三角的一端指向父类,另一端连接子类。

关联关系

关联(Assocition)关系是类与类之间最常见的一种关系,它是一种结构化的关系,表示一个对象与另一个对象之间有联系,如汽车和轮胎、师傅和徒弟、班级和学生等。在UML类图中,用(带接头或不带箭头的)实线连接有关联关系的类。在C++中这种关联关系在类中是这样体现的,通常将一个类的对象作为另一个类的成员变量。

类之间的关联关系有三种,分别是:单向关联、双向关联、自关联。

单向关联 

单向关联指的是关联只有一个方向,比如每个孩子(Child)都拥有一个父亲(Parent) 

class Parent
{
};

class Child
{
private:
    Parent m_father;
};

 

如果是单向关联,使用的连接线是带单向箭头的实线, 哪个类作为了当前类的成员变量,那么箭头就指向哪个类。在这个例子中 Parent 类 作为了Child 类的成员变量,因此箭头端应该指向Parent 类,另一端连接 Child 类。

双向关联

你中有我,我中有你

class Parent
{
private:
    Child m_son;
};

class Child
{
private:
    Parent m_father;
};

或者使用双向箭头表示

 

自关联关系

自关联指的就是当前类中包含一个自身类型的对象成员,这在链表中非常常见,单向链表中都会有一个指向自身节点类型的后继指针成员,而双向链表中会包含一个指向自身节点类型的前驱指针和一个指向自身节点类型的后继指针。就以双向链表节点类为例,它的C++写法为:

class Node 
{
private:
    void* m_data;
    Node* m_prev;
    Node* m_next;
};

 一般使用带箭头的实线来描述自关联关系,我中有我。但是有些UML绘图软件表示类与类的关联关系,使用的就是一条实线,没有箭头。

聚合关系

聚合(Aggregation)关系表示整体与部分的关系。在聚合关系中,成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在。在UML中聚合关系用带空心菱形的直线表示,下面举两个聚合关系的例子:

  • 汽车(Car)与 引擎(Engine)、轮胎(Wheel)、车灯(Light)
  • 森林(Forest)与 植物(Plant)、动物(Animal)、水(Water)、阳光(Sunshine)

class Plant
{
    // 植物
};

class Animal
{
    // 动物
};

class Water
{
    // 水
};

class Sunshine
{
    // 阳光
};

class Forest
{
public:
    Forest(Plant p, Animal a, Water w, Sunshine s) : 
        m_plant(p),m_animal(a),m_water(w),m_sun(s)
    {
    }
private:
    Plant m_plant;
    Animal m_animal;
    Water m_water;
    Sunshine m_sun;
};

 

uml一般只需要画出关键函数即可,关于析构函数和构造函数看你喜欢!

~+ ~Forest( )表示公共析构函数 

部分与整体之间并没有相同的生命周期,整体消亡后部分可以独立存在。就像大雁和雁群是聚合关系。代码实现时,整体类中传入一个部分类的指针,部分类已经在整体类外被构造,因而在整体类析构的时候,部分类并没有被析构。

组合关系

组合(Composition)关系也表示的是一种整体和部分的关系,但是在组合关系中整体对象可以控制成员对象的生命周期,一旦整体对象不存在,成员对象也不存在,整体对象和成员对象之间具有同生共死的关系。

在UML中组合关系用带实心菱形的直线表示,下面举两个组合关系的例子:

  • 头(Head)和 嘴巴(Mouth)、鼻子(Nose)、耳朵(Ear)、眼睛(Eye)
  • 树(Tree)和 树根(Root)、树干(Trunk)、树枝(Branch)、树叶(Leaf)

因为头没了,嘴巴、鼻子...都没了

class Root
{
};

class Trunk
{
};

class Branch
{
};

class Leaf
{
};

class Tree
{
public:
    Tree()
    {
        m_root = new Root;
        m_trunk = new Trunk;
        m_branch = new Branch;
        m_leaf = new Leaf;
    }
    ~Tree()
    {
        delete m_root;
        delete m_trunk;
        delete m_branch;
        delete m_leaf;
    }
private:
    Root* m_root;
    Trunk* m_trunk;
    Branch* m_branch;
    Leaf* m_leaf;
};

 

依赖关系

依赖(Dependency)关系是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系,大多数情况下依赖关系体现在某个类的方法使用另一个类的对象作为参数。

在UML中依赖关系用带箭头的虚线表示,由依赖的一方指向被依赖的一方

可以用排除法(排除前面几种)来确定

依赖关系通常通过三种方式来实现:

①将一个类的对象作为另一个类中方法的参数
②在一个类的方法中将另一个类的对象作为其对象的局部变量
③在一个类的方法中调用另一个类的静态方法

驾驶员(Driver)开车,需要将车(Car)对象作为参数传递给 Driver 类的drive()方法。

class Car 
{ 
public: 
    void move() {}
}; 

class Driver 
{
public: 
    void drive(Car car) 
    { 
        car.move(); 
    } 
};

树木(Tree)的生长,需要将空气(Air)、水(Water)、土壤(Soil)对象作为参数传递给 Tree 类的 grow()方法。

class Water
{
};

class Air
{
};

class Soil
{
};

class Tree
{
public:
    void grow(Water w, Air a, Soil s) 
    {
        cout << "借助 w 中的水分, s 中的养分和 a 中的二氧化碳, 我就可以茁壮成长了";
    }
};

 

类之间的关系强弱顺序是这样的:继承(泛化) >  组合  >  聚合  >  关联  >  依赖。 

关联关系、聚合关系、组合关系之间的区别 

实际应用中,这三种关系的界限划分其实没有那么清楚,有些时候我们会感觉组合和聚合没什么区别,所以,在设计的时候没必要死抠细节,只要能够利用对象之间的关系设计出可行的解决方案即可。

①朋友之间属于关联关系,因为这种关系是平等的,关联关系只是用于表示两个对象之间的一种简单的联系而已。
②图书馆看书的时候,人和书属于聚合关系。书是可以独立存在的,而且书不仅可以属于自己,也可以属于别人。
③人和自己的心脏属于组合关系,因为心脏不能脱离人体而独自存在。
参考: 爱编程的大丙

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212388.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能和机器学习之线性代数(一)

人工智能和机器学习之线性代数&#xff08;一&#xff09; 人工智能和机器学习之线性代数一将介绍向量和矩阵的基础知识以及开源的机器学习框架PyTorch。 文章目录 人工智能和机器学习之线性代数&#xff08;一&#xff09;基本定义标量&#xff08;Scalar&#xff09;向量&a…

通过观测云 DataKit Extension 接入 AWS Lambda 最佳实践

前言 AWS Lambda 是一项计算服务&#xff0c;使用时无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行代码并自动缩放。借助 AWS Lambda&#xff0c;几乎可以为任何类型的应用程序或后端服务运行代码&#xff0c;而且无需执行任何管理。 Lambda Layer 是一个包…

5 个免费高清无水印视频素材库

短视频创作&#xff0c;素材是关键。以下为你推荐 5 个超棒的免费且无版权的高清无水印短视频素材网站&#xff0c;助你获取创作资源。 蛙学网 国内顶级素材站&#xff0c;有海量高质量素材&#xff0c;领域涉及自然风光、情感生活、游戏动漫以及社会人文等。其素材均为 4K 高…

集合框架07:LinkedList使用

1.视频链接&#xff1a;13.14 LinkedList使用_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?spm_id_from333.788.videopod.episodes&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p142.LinkedList集合的增删改查操作 package com.yundait.Demo01;im…

Vmware开箱即用win7系统

下载文件 下载VMWare与win7成品虚拟机资料&#xff08;PS&#xff1a;里面有Win10 和Win11&#xff0c;使用方法都是一样的&#xff09; ⏬下载链接⏬ 下载链接 使用虚拟机打开成品虚拟机

python怎么引用文件

新建python文件 &#xff1a;在同目录lib下创建mylib.py和loadlib.py两个文件。 在mylib.py文件中创建一个Hello的类&#xff0c;并且给这个类添加一个sayHello的方法&#xff0c;让它输出hello python 在loadlib.py 文件中引入mylib import mylib 在loadlib中调用引用过来的py…

QT开发--串口通信

第十六章 串口通信 16.1 串口通信基础 串口通信主要通过DB9接口&#xff0c;适用于短距离&#xff08;<10米&#xff09;。关键参数包括&#xff1a; 波特率&#xff1a;每秒传输bit数&#xff0c;如9600。数据位&#xff1a;信息包中的有效数据位数。停止位&#xff1a;…

Excel:vba实现禁止新增工作表

实现效果&#xff1a;禁止新增工作表 步骤如下&#xff1a; 1.点击开发工具里面的Visual Basic 2.不要自己创建&#xff0c;点击ThisWorkbook&#xff0c;点击选择Workbook&#xff0c;点击选择NewSheet 这里的NewSheet就是工作簿事件 代码如下&#xff1a; 这是事件处理程序…

day∞-过滤器-拦截器

一、过滤器 二、拦截器

【Java面试——基础知识——Day5】

1. 异常 1.1 Exception 和 Error 有什么区别&#xff1f; 在 Java 中&#xff0c;所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类: Exception :程序本身可以处理的异常&#xff0c;可以通过 catch 来进行捕获。Exception 又可以…

二叉树LeetCode刷题

二叉树LeetCode刷题 1. 检查两颗树是否相同2. 另一颗树的子树3. 翻转二叉树4. 判断一颗二叉树是否是平衡二叉树5. 二叉搜索树与双向链表6. 对称二叉树7. 二叉树的构建及遍历8. 二叉树的分层遍历9. 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先10. 根据一棵树的前序遍…

算法竞赛(Python)-AI的思维模式(搜索)

文章目录 一 、深度优先搜索1 零钱搭配2“油漆桶”与连通性 二 、记忆化三、在游戏中制胜的AI1 永远的平局——井字棋2 一起来解谜——数独3 数字华容道 一 、深度优先搜索 深度优先搜索是最基本的搜索方法&#xff0c;在深度优先搜索的过程中&#xff0c;如果把所有的可行解看…

如果你的YOLO环境已经配置好了,如何打开项目文件

1.首先将【目标检测系统源码】下载完成之后&#xff0c;解压到某个路径下&#xff08;可以解压在D盘或者F盘都可&#xff09;。然后使用Pycharm打开这个项目文件。 2.使用 pip 命令安装所需的依赖&#xff0c;可以通过requirements.txt文件进行安装。请务必按照 requirements.t…

springboot第76集:线程,ThreadGroup

导出数据&#xff1a; 查询结果可以使用脚本或工具&#xff08;如 Python 的 Pandas 库&#xff09;将数据导出为 Excel 格式。例如&#xff0c;使用 Python&#xff1a; 当查询数组中有大量数据&#xff08;如一千多条&#xff09;时&#xff0c;可以使用 _mget&#xff08;多…

系统分析师17:系统安全分析与设计

1 内容概述 2 对称加密与非对称加密技术 在信息安全领域&#xff0c;对称加密和非对称加密是两种最常见的加密技术。它们各自有不同的特点和应用场景&#xff0c;下面将详细介绍这两种加密技术。 2.1 对称加密 2.1.1 概念 对称加密是指使用相同的密钥&#xff08;也称为密钥…

opencv学习:风格迁移对图像风格进行更改

介绍&#xff1a; 风格迁移是一种计算机视觉技术&#xff0c;它能够让一张图片看起来像是用另一种风格画出来的。想象一下&#xff0c;你有一张普通的照片&#xff0c;但你希望它看起来像是梵高的印象派画作&#xff0c;或者像是某个著名艺术家的作品&#xff0c;风格迁移就可以…

C语言 ——— oj题:搜索插入位置

目录 题目要求 代码实现 题目要求 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置 请必须使用时间复杂度为 O(long n) 的算法 示例 1: 输入: nums [1,3,5,6], t…

golang包管理

package 在工程化的Go语言开发项目中&#xff0c;Go语言的源码复用是建立在包&#xff08;package&#xff09;基础之上的。本文介绍了Go语言中如何定义包、如何导出包的内容及如何导入其他包。 包与依赖管理 本章学习目标 掌握包的定义和使用掌握init初始化函数的使用掌握…

一、el-table的滚动条加粗并解决遮挡内容问题

近期接到产品提的需求&#xff0c;反馈用户说table里面的滚动条过小&#xff0c;不方便拖动&#xff0c;希望加粗&#xff0c;然后我就研究了下如何加粗&#xff0c;发现加粗后会导致遮挡内容的问题&#xff0c;并予以解决。以下是实现和解决的方法和步骤。 先看看官网的滚动条…

[翻译]MOSIP 101

目录 Architecture Principles of MOSIP &#xff08;MOSIP架构原则&#xff09; MOSIP Functional Architecture&#xff08;MOSIP功能架构&#xff09; MOSIP Features&#xff08;MOSIP特点&#xff09; MOSIP Modules&#xff08;MOSIP模块&#xff09; MOSIP Logical…