UML(统一建模语言)

面向对象设计主要就是使用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.rhkb.cn/news/446339.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ROS2 “通信方式” 参数服务器

为什么加“通信方式”引号&#xff0c;因为我觉得他就不算通信&#xff0c;最多最多就是一个动态加载参数方式 所以ros通信方式就三种&#xff0c;topic service action 别犟&#xff0c;犟就是你对&#xff01; 常用的 param参数方法如下&#xff1a; # declare_parameter…

五款专业三维数据处理工具:GISBox、Cesiumlab、OSGBLab、灵易智模、倾斜伴侣深度解析

随着三维数据处理技术的广泛应用&#xff0c;尤其是在城市规划、地理信息系统&#xff08;GIS&#xff09;、工程监测等领域&#xff0c;处理倾斜摄影、三维建模以及大规模数据管理的需求日益增加。以下是五款我精心挑选的倾斜摄影和三维数据处理工具——GISBox、Cesiumlab、OS…

视频号直播自动回复与循环发送话术-自动化插件

我们在做视频号直播的时候&#xff0c;会有这种自动回复咨询问题的功能 唯一客服浏览器插件现在就支持&#xff0c;在视频号直播后台&#xff0c;自动化回复用户问题&#xff0c;以及循环发送我们的介绍话术

第十四章 RabbitMQ延迟消息之延迟队列

目录 一、引言 二、死信队列 三、核心代码实现 四、运行效果 五、总结 一、引言 什么是延迟消息&#xff1f; 发送者发送消息时指定一个时间&#xff0c;消费者不会立刻收到消息&#xff0c;而是在指定时间后收到消息。 什么是延迟任务&#xff1f; 设置在一定时间之后才…

【动手学深度学习】6.3 填充与步幅(个人向笔记)

卷积的输出形状取决于输入形状和卷积核的形状在应用连续的卷积后&#xff0c;我们最终得到的输出大小远小于输入大小&#xff0c;这是由于卷积核的宽度和高度通常大于1导致的比如&#xff0c;一个 240 240 240240 240240像素的图像&#xff0c;经过10层 5 5 55 55的卷积后&am…

Mac 下编译 libaom 源码教程

AV1 AV1是一种开放、免版税的视频编码格式&#xff0c;由开放媒体联盟&#xff08;AOMedia&#xff09;开发&#xff0c;旨在提供高压缩效率和优秀的视频质量。AV1支持多种分辨率&#xff0c;包括SD、HD、4K和8K&#xff0c;并适用于视频点播&#xff08;VOD&#xff09;、直播…

2014年国赛高教杯数学建模B题创意平板折叠桌解题全过程文档及程序

2014年国赛高教杯数学建模 B题 创意平板折叠桌 某公司生产一种可折叠的桌子&#xff0c;桌面呈圆形&#xff0c;桌腿随着铰链的活动可以平摊成一张平板&#xff08;如图1-2所示&#xff09;。桌腿由若干根木条组成&#xff0c;分成两组&#xff0c;每组各用一根钢筋将木条连接…

Redis——持久化

文章目录 Redis持久化Redis的两种持久化的策略定期备份&#xff1a;RDB触发机制rdb的触发时机&#xff1a;手动执行save&bgsave保存测试不手动执行bgsave测试bgsave操作流程测试通过配置&#xff0c;自动生成rdb快照RDB的优缺点 实时备份&#xff1a;AOFAOF是否会影响到red…

基于opencv答题卡识别判卷

我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色&#xff1a;深度实…

【Qt】窗口预览(1)—— 菜单栏

窗口预览&#xff08;1&#xff09; 1. QMainWindow2. QMenuBar——菜单栏2.1 创建菜单栏/将菜单栏添加到widget中2.2 addMenu——在菜单栏中添加菜单2.3 在菜单中添加选项2.4 添加快捷键2.5 支持嵌套添加菜单2.6 添加信号2.7 添加分割线 1. QMainWindow Qt窗口是通过QMainWin…

基于SSM框架学籍管理系统的设计与实现

我 | 在这里 ⭐ 全栈开发攻城狮、全网10W粉丝、2022博客之星后端领域Top1、专家博主。 &#x1f393;擅长 指导毕设 | 论文指导 | 系统开发 | 毕业答辩 | 系统讲解等。已指导60位同学顺利毕业 ✈️个人公众号&#xff1a;乡下小哥编程。回复 Java全套视频教程 或 前端全套视频教…

微信小程序和抖音小程序的分享和广告接入代码

开发完成小程序或者小游戏之后&#xff0c;我们为什么要接入分享和广告视频功能&#xff0c;主要原因有以下几个方面。 微信小程序和抖音小程序接入分享和广告功能主要基于以下几个原因&#xff1a; 用户获取与增长&#xff1a;分享功能可以帮助用户将小程序内容传播给更多人&…

# 在执行 rpm 卸载软件使用 nodeps 参数时,报错 error: package nodeps is not installed 分析

在执行 rpm 卸载软件使用 nodeps 参数时&#xff0c;报错 error: package nodeps is not installed 分析 一、问题描述&#xff1a; 在执行 rpm 卸载软件使用 nodeps 参数时&#xff0c;报错 error: package nodeps is not installed 如下图&#xff1a; 二、报错分析&…

【HarmonyOS NEXT】实现页面水印功能

关键词&#xff1a;鸿蒙、水印、Watermark、页面、触摸问题 注&#xff1a;本期文章同样适用 OpenHarmony 的开发 在app开发过程中时常会出现敏感信息页面&#xff0c;为保护信息安全和及时的数据追踪&#xff0c;通常会采用给页面加水印的形式&#xff0c;那么本期文章会介绍…

ARC学习(4)基本编程模型认识(四)----寄存器以及异常数据读取

笔者来聊一下ARC寄存器的获取 在介绍了ARC编程模型的知识点之后,来看一些具体的编程操作,比如如何获取寄存器,如何编写汇编语言实现特定功能? 1、获取寄存器 可以使用内联汇编来实现寄存器的获取,具体格式如下: _Asm:汇编宏标识符,指示内联汇编代码_Save_all_regs:…

轻量服务器和云服务器ecs哪个好用一些?

轻量服务器和云服务器ecs哪个好用一些&#xff1f;轻量服务器与云服务器ECS在多方面存在显著差异&#xff0c;对于需要高性能计算和大规模数据处理的用户来说&#xff0c;ECS可能是更好的选择&#xff1b;而对于预算有限且需求较为简单的用户来说&#xff0c;轻量服务器可能更为…

Node.js入门——fs、path模块、URL端口号、模块化导入导出、包、npm软件包管理器

Node.js入门 1.介绍 定义&#xff1a;跨平台的JS运行环境&#xff0c;使开发者可以搭建服务器端的JS应用程序作用&#xff1a;使用Node.Js编写服务器端代码Node.js是基于Chrome V8引擎进行封装&#xff0c;Node中没有BOM和DOM 2.fs模块-读写文件 定义&#xff1a;封装了与…

分布式事务管理-Seata从入门到精通

一、基本概念 什么是数据库事务&#xff1f; 1、一个操作数据库数据的执行单元 2、到围从开始到结束的多个操作组成 3、事务内的多个操作要么都成功,要么都失败 什么是分布式事务&#xff1f; 1.分布式场景下&#xff0c;完成某一个业务功能可能需要横跨多个服务&#xff0…

jmeter入门:脚本录制

1.设置代理。 网络连接-》代理-》手动设置代理. ip&#xff1a; 127.0.0.1&#xff0c; port&#xff1a;8888 2. add thread group 3. add HTTP(s) test script recorder, target controller chooses Test plan-> thread Group 4. click start. then open the browser …

AIGC毕设项目分享:基于RAG的数字人对话系统及其应用

本研究的主要目标是设计并实现一个基于检索增强生成&#xff08;RAG&#xff09;技术的数字人对话系统&#xff0c;旨在提升数字人系统在多轮对话中的上下文管理、情境感知能力以及动态内容生成效果。系统结合了深度学习中的最新大语言模型技术&#xff0c;通过引入RAG框架来增…