当前位置: 首页 > news >正文

【设计模式】UML类图和六大设计原则

前言

在实践中经常看到工厂模式、观察者模式等字眼,渐觉设计模式的重要性,于是开刷设计模式。

本文讲述了UML类图以及设计模式的六大原则

参考资料:

课程视频:黑马程序员Java设计模式

一、UML类图

1. 类和接口的表示方式

在这里插入图片描述

如图所示,在 UML 类图中,第一栏为类的名称,第二栏为类的属性(field),第三栏为类的方法(method)

属性/方法之前的 - + # 表示访问权限:
- 表示 private
+ 表示 public
# 表示 protected

属性的完整表示方式是: 可见性 名称 :类型 [= 缺省值]
方法的完整表示方式是: 可见性 名称(参数列表)[:返回类型]

接口图 和 类图 的主要区别是顶端有 <<interface>>

2. 关联和双向关联

关联关系表示存在对象的引用,如 A 类中某一个成员变量的类型为 B 类,那么 A 类依赖于 B 类

在这里插入图片描述

关联关系使用 实心箭头 表示

在这里插入图片描述

双向关联使用 横线 表示

3. 组合和聚合

组合聚合 都是关联的特例,强调整体和部分的关系,在转换为关系模型时跟关联没有区别,但是在
UML 中的描述存在语义上的区别。

组合

组合 中的整体和部分具有强依赖,整体的对象负责部分的对象的生命周期,如鸟和翅膀
在这里插入图片描述

组合关系用 实心菱形+横线/实线箭头 表示

聚合

而聚合的整体和部分可以独立存在,如汽车和轮胎,部门和员工

在这里插入图片描述

聚合关系用 空心菱形+横线/实线箭头 表示

3. 依赖、继承、实现

依赖

依赖是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。

表示一个类中的方法通过 局部变量、方法的参数或者对静态方法 的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。
在这里插入图片描述

依赖关系用 虚线箭头 表示

继承

继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系

在这里插入图片描述

继承关系用 空心三角实线箭头 表示

实现

实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。

在这里插入图片描述

实现关系用 空心三角虚线箭头 表示

二、六大设计原则

1. 开闭原则

开闭原则 即 对扩展开放,对修改关闭

在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。

简言之,是为了使程序的扩展性好,易于维护和升级。

实现方式是使用 接口派生类

2. 里氏代换原则

里氏代换原则 即 任何基类可以出现的地方,子类一定可以出现

通俗理解: 子类可以扩展父类的功能,但不能改变父类原有的功能

换句话说,子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法

【例子】

如果让 正方形类 继承 长方形类(包含 setLength(), setWidth()方法)

在这里插入图片描述

那么正方形类会重写长方形类的这两个方法,以实现自身的逻辑,从而违反里氏代换原则

修正方案:
在这里插入图片描述

新建 Quadrilateral 接口,让长方形和正方形分别去实现该接口,而使用长方形的类依赖该接口

3. 依赖倒转原则

依赖倒转原则 即 高层模块不应该依赖低层模块,两者都应该依赖其抽象;

抽象不应该依赖细节,细节应该依赖抽象。简单的说就是要求对抽象进行编程

不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

【例子】

电脑有多种配件比如cpu,显卡,显示器

电脑不应该依赖于特定品牌的cpu,显卡,显示器,也就是不能依赖于实现

而是应该依赖于cpu,显卡,显示器它们的抽象

4. 迪米特法则

迪米特法则 又叫最小知识法则

其含义是: 如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。

其目的是降低类之间的耦合度,提高模块的相对独立性。

迪米特法则的

【例子】

明星通过经纪人组织与粉丝的见面会

甲方公司通过乙方公司把需求拍给牛马

5. 接口隔离原则

接口隔离原则 即 客户端不应该被迫依赖于它不使用的方法; 一个类对另一个类的依赖应该建立在最小的接口上

实现上采用将 包含多个方法的接口 分解为 多个只包含少量方法的接口

【例子】

一个品牌的安全门实现了 防火、防水、防盗

另一个品牌的安全门实现了 防火、防水

若定义接口 包含 防火、防水、防盗 三个功能,那么第二个类就被迫依赖于它不使用的防盗方法

故定义三个接口分别为 防火、防水、防盗

6. 合成复用原则

合成复用原则 即 尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。

继承会将父类的细节暴露给子类,破坏了类的封装性,使子类与父类耦合度高,限制了复用的灵活性。

【例子】

现有父类为汽车,子类继承汽车,分别为汽油汽车和新能源汽车,孙子类继承汽油汽车/新能源汽车再拓展不同颜色的汽车

在这里插入图片描述

可见,再给汽车增加一种类型的动力源时,会出现很多的孙子类,扩展性很差。

修改方案:

在这里插入图片描述

父类为汽车,包含颜色属性(聚合颜色这一接口,而颜色这一接口可被各种颜色所实现),子类继承汽车使用不同的动力源

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [基于 Vue CLI 5 + Vue 3 + Ant Design Vue 4 搭建项目] 08 创建项目的目录结构介绍
  • ggplot2 缩小的/一般长度的、带箭头的坐标轴 | R语言
  • django自用教程
  • 3个WebSocket的.Net开源项目
  • 赋能百业:多模态处理技术与大模型架构下的AI解决方案落地实践
  • 【Mysql】记录sql在执行过程中很慢
  • 配电房数字式仪表读数识别算法开发
  • 开放式激光振镜运动控制器在Ubuntu+Qt下的文本标刻
  • Leetcode3271. 哈希分割字符串
  • Tranformer分布式特辑
  • 【C++】Stack
  • 【ShuQiHere】探索人工智能核心:机器学习的奥秘
  • 计算机毕业设计 智能推荐旅游平台 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
  • Spring Boot之DevTools介绍
  • 网络安全 DVWA通关指南 DVWA Reflected Cross Site Scripting (反射型 XSS)
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 4个实用的微服务测试策略
  • 78. Subsets
  • httpie使用详解
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Javascript 原型链
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Yii源码解读-服务定位器(Service Locator)
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 后端_ThinkPHP5
  • 跨域
  • 移动端唤起键盘时取消position:fixed定位
  • 自制字幕遮挡器
  • Linux权限管理(week1_day5)--技术流ken
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ${ }的特别功能
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (pytorch进阶之路)扩散概率模型
  • (二十四)Flask之flask-session组件
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (七)c52学习之旅-中断
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (四)js前端开发中设计模式之工厂方法模式
  • (未解决)macOS matplotlib 中文是方框
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)linux下的时间函数使用
  • (转)winform之ListView
  • (转)视频码率,帧率和分辨率的联系与区别
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • ... 是什么 ?... 有什么用处?
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .Net接口调试与案例
  • .NET开源、简单、实用的数据库文档生成工具
  • .NET中使用Protobuffer 实现序列化和反序列化
  • /etc/sudoer文件配置简析