【设计模式】设计模式基础

news2024/11/19 6:37:44

设计模式基础

文章目录

  • 设计模式基础
    • 一、七大设计原则
      • 1.1 概述
      • 1.2 单一职责原则
      • 1.3 接口隔离原则
      • 1.4 依赖倒转原则
      • 1.5 里氏替换原则
      • 1.6 开闭原则
      • 1.7 迪米特法则
      • 1.8 合成复用原则
    • 二、UML类图
      • 2.1 概述
      • 2.2 依赖关系(Dependence)
      • 2.3 泛化关系(generalization)
      • 2.4 实现关系(Implementation)
      • 2.5 关联关系(Association)
      • 2.6 聚合关系(Aggregation)
      • 2.7 组合关系(Aggregation)
    • 三、设计模式
    • 参考链接

一、七大设计原则

1.1 概述

设计模式是为了让程序(软件),具有更好代码重用性,可读性,可扩展性,可靠性。使程序呈现高内聚,低耦合的特性。

设计模式原则,其实就是程序员在编程时,应当遵守的原则,也是各种设计模式的基础(即: 设计模式为什么这样设计的依据)

  1. 单一职责原则
  2. 接口隔离原则
  3. 依赖倒转(倒置)原则
  4. 里氏替换原则
  5. 开闭原则
  6. 迪米特法则
  7. 合成复用原则

1.2 单一职责原则

一个类应该只负责一项职责,如实体类,实体类中不应进行其他业务操作。

举例,比如在一个绘图系统中,定义一个矩形类,类中包含了长、宽,同时定义了一个绘制矩形的方法,在这个方法中难免要使用到GUI库的引用,这会导致程序在加载矩形类的时候也消耗链接、编译时间、内存空间和存储空间等。其次在绘制矩阵方法中,绘制方法中可能用到自定义的绘制方法,当有需求要更改自定义的绘制方法时,就强制要求将矩形类也要重新编译,测试及部署。

职责的统一需要根据业务和需求来判断,识别出同一种类型的职责,这也是比较难的一点。

1.3 接口隔离原则

一个类对另一个类的依赖应该建立在最小的接口

当一个类依赖于某个接口的部分方法,而不是全部方法时,应考虑将接口拆分,而不是增加多余的空实现

1.4 依赖倒转原则

依赖倒转(倒置)的中心思想是:面向接口编程,比如接收信息,只依赖于接收信息接口,在后续增加接收信息的方式时,调用方无需修改代码即可无缝衔接

  1. 高层模块都不应依赖底层模块的实现,而应只依赖于抽象
  2. 抽象也不应该依赖于细节,细节应该依赖于抽象
  3. 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成

依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在 java 中,抽象指的是接口或抽象类,细节就是具体的实现类

1.5 里氏替换原则

问题提出:在编程中,如何正确的使用继承? => 里氏替换原则

继承包含这样一层含义:父类中凡是已经实现好的方法,实际上是在设定规范和契约,虽然它不强制要求所有的子类必须遵循这些契约,但是如果子类对这些已经实现的方法任意修改,就会对整个继承体系造成破坏。

继承在给程序设计带来便利的同时,也带来了弊端。比如使用继承会给程序带来侵入性,程序的可移植性降低,增加对象间的耦合性,如果一个类被其他的类所继承,则当这个类需要修改时,必须考虑到所有的子类,并且父类修改后,所有涉及到子类的功能都有可能产生故障。

  1. 如果对每个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。换句话说,所有引用基类的地方必须能透明地使用其子类的对象
  2. 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法
  3. 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过 聚合,组合,依赖 来解决问题

1.6 开闭原则

开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则

  1. 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节即创建多个实现类实现不同细节。
  2. 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
  3. 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。

1.7 迪米特法则

迪米特法有个简单的定义:只与直接的朋友通信

直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量,方法参数,方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

  1. 一个对象应该对其他对象保持最少的了解
  2. 类与类关系越密切,耦合度越大
  3. 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的 public 方法,不对外泄露任何信息

1.8 合成复用原则

原则是尽量使用组合/聚合的方式,而不是使用继承

二、UML类图

2.1 概述

Uml图种类:

  1. 用例图
  2. 静态结构图:类图、对象图、包图、组件图、部署图
  3. 动态行为图:交互图(时序图与协作图)、状态图、活动图

针对于设计模式,必须先弄懂类图

  1. 用于描述系统中的类(对象)本身的组成和类(对象)之间的各种静态关系
  2. 类之间的关系:依赖、泛化(继承)、实现、关联、聚合与组合

2.2 依赖关系(Dependence)

只要是在类中用到了对方,那么他们之间就存在依赖关系。如果没有对方,连编绎都通过不了

public class PersonServiceBean {
	private PersonDao personDao;
	public void save(Person person){}
	public IDCard getIDCard(Integer personid){}
	public void modify(){
		Department department = new Department();
	}
}

对应关系:普通箭头

在这里插入图片描述

2.3 泛化关系(generalization)

泛化关系实际上就是继承关系,它是依赖关系的特例

public class PersonServiceBean extends Daosupport{
}

对应关系:空心箭头指向类

在这里插入图片描述

2.4 实现关系(Implementation)

实现关系实际上就是 A 类实现 B 接口,它是依赖关系的特例

public class PersonServiceBean implements PersonService {
	public void delete(Interger id){}
}

对应关系:空心箭头指向接口

在这里插入图片描述

2.5 关联关系(Association)

类与类之间的联系,它是依赖关系的特例

关联具有导航性:即双向关系或单向关系

关联具有多重性:如“1”对“多”,“多”对“多”

单向 1 对 1 关联关系:

public class Person {
	private IDCard card;
}

双向 1 对 1 关联关系:

public class Person {
	private IDCard card;
}
// 另一个文件
public class IDCard{
	private Person person;
}

对应图:

  • 单向:普通箭头加数字
  • 双向:直线加数字

在这里插入图片描述

2.6 聚合关系(Aggregation)

聚合关系(Aggregation)表示的是整体和部分的关系,整体与部分可以分开聚合关系是关联关系的特例,所以他具有关联的导航性与多重性

如:一台电脑由键盘(keyboard)、显示器(monitor),鼠标等组成;组成电脑的各个配件是可以从电脑上分离出来的,使用带空心菱形的实线来表示:

public class Computer{
	private Mouse mouse;
	private Monitor monitor;

	public void setMouse(Mouse mouse) {
		this.mouse = mouse;
	}

	public void setMonitor(Monitor monitor) {
		this.monitor = monitor;
	}
}

2.7 组合关系(Aggregation)

组合关系:也是整体与部分的关系,但是整体与部分不可以分开。用实心菱形表示。

如果我们认为上面Mouse,Monitor和Computer是不可分离的,则升级为组合关系

public class Computer{
	private Mouse mouse = new Mouse();
	private Monitor monitor = new Monitor();
}

再看一个案例:在程序中我们定义实体:Person 与 IDCard、Head, 那么 Head 和 Person 就是 组合,IDCard 和Person 就是聚合。

但是如果在程序中 Person 实体中定义了对 IDCard 进行级联删除,即删除 Person 时连同 IDCard 一起删除,那么 IDCard 和 Person 就是组合了。

public class Person{
	private IDCard card;
	private Head head = new Head();
}

在这里插入图片描述

三、设计模式

可以分为三大类:

创建型模式(Creational Patterns):这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。

  1. 工厂模式(Factory Pattern)
  2. 抽象工厂模式(Abstract Factory Pattern)
  3. 单例模式(Singleton Pattern)
  4. 建造者模式(Builder Pattern)
  5. 原型模式(Prototype Pattern)
  6. 对象池模式 *(Pool)
  7. 多例模式 *(Multiton)
  8. 静态工厂模式 *(Static Factory)

结构型模式(Structural Patterns):这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。

  1. 适配器模式(Adapter Pattern)
  2. 桥接模式(Bridge Pattern)
  3. 过滤器模式(Filter、Criteria Pattern)
  4. 组合模式(Composite Pattern)
  5. 装饰器模式(Decorator Pattern)
  6. 外观模式(Facade Pattern)
  7. 享元模式(Flyweight Pattern)
  8. 代理模式(Proxy Pattern)
  9. 数据映射模式 *(Data Mapper)
  10. 依赖注入模式 *(Dependency Injection)
  11. 门面模式 *(Facade)
  12. 流接口模式 *(Fluent Interface)
  13. 注册模式 *(Registry)

行为型模式(Behavioral Patterns):这些设计模式特别关注对象之间的通信

  1. 责任链模式(Chain of Responsibility Pattern)
  2. 命令模式(Command Pattern)
  3. 解释器模式(Interpreter Pattern)
  4. 迭代器模式(Iterator Pattern)
  5. 中介者模式(Mediator Pattern)
  6. 备忘录模式(Memento Pattern)
  7. 观察者模式(Observer Pattern)
  8. 状态模式(State Pattern)
  9. 空对象模式(Null Object Pattern)
  10. 策略模式(Strategy Pattern)
  11. 模板模式(Template Pattern)
  12. 访问者模式(Visitor Pattern)
  13. 规格模式 *(Specification)
  14. 访问者模式 *(Visitor)

设计模式之间的关系
在这里插入图片描述

参考链接

https://baijiahao.baidu.com/s?id=1757590341900686107&wfr=spider&for=pc

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

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

相关文章

YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进【NO.79】改进损失函数为VariFocal Loss

前言 作为当前先进的深度学习目标检测算法YOLOv8,已经集合了大量的trick,但是还是有提高和改进的空间,针对具体应用场景下的检测难点,可以不同的改进方法。此后的系列文章,将重点对YOLOv8的如何改进进行详细的介绍&…

Linux MMC子系统 - 5.eMMC 5.1工作模式-引导模式

By: Ailson Jack Date: 2023.11.19 个人博客:http://www.only2fire.com/ 本文在我博客的地址是:http://www.only2fire.com/archives/164.html,排版更好,便于学习,也可以去我博客逛逛,兴许有你想要的内容呢。…

Windows 下 Sublime Text 3.2.2 下载及配置

1 下载地址: https://www.sublimetext.com/3 Sublime Text 3.2.2 (此版本选择了 portable version),直接解压就可以使用。 https://download.sublimetext.com/Sublime Text Build 3211.zip 2 相关配置 2.1 取消自动更新(需重启): Preferen…

新手必看!!超详细!STM32-基本定时器

一、基本定时器的作用 定时触发输出直接驱动DAC。 二、基本定时器的框图 以STM32F103系列为例,具体开发板请查看开发手册。 类别定时器总线位数计数方向预分频系数是否可以产生DMA捕获/比较通道互补输出基本定时器TIM6 / TIM7APB116位向上1~65536可以0无通用定时…

关于MySQL安装时一直卡在starting sever......手把手教你搞定

🎈🎈🎈很多人刚开始安装MySQL的时候会出现卡在starting sever..的情况,今天手把手教大家轻松搞定! 首先出现这个问题的原因有两个: 1. 你的电脑用户名是中文的。 2. 你前一次安装的MySQL没有完全删除干净。…

Halcon (3):窗体常用语法使用

文章目录 文章专栏视频资源前言halcon图像使用加载图片示例绘制常用图像批量批注绘制 文章专栏 Halcon开发 视频资源 机器视觉之C#联合Halcon 前言 在使用halcon的算子之前,我们要先学会如何在图片上面进行标注。因为我们不仅要导出处理的结果,还要导出…

Vue3问题:如何实现el-tree树的单选?

前端功能问题系列文章,点击上方合集↑ 序言 大家好,我是大澈! 本文约1400字,整篇阅读大约需要3分钟。 本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。 …

springboot+activiti5.22.0集成Activiti在线流程设计器

SpringBoot集成Activiti5.22在线流程设计器 文章目录 SpringBoot集成Activiti5.22在线流程设计器📝1.增加配置pom依赖 增加数据库及redis配置文件📜 2.启动类ActivitiDesignApplication排除安全校验注解启动项目后将会自动在数据库中生成表 &#x1f4d8…

MySQL 的执行原理(二)

5.3. MySQL 的查询成本 5.3. MySQL 的查询成本 MySQL 执行一个查询可以有不同的执行方案,它会选择其中成本最低,或者 说代价最低的那种方案去真正的执行查询。不过我们之前对成本的描述是非常模 糊的,其实在 MySQL 中一条查询语句的执行成本…

游戏数据分析必知必会

游戏的分类 按端分类:端游(steam),页游(4399),手游(手机,pad)按盈利模式分类:付费游戏(一次买断,后续购买其它剧情或者包…

使用内网穿透解决支付宝回调地址在公网问题

使用natapp解决内网穿透问题 前言NATAPP使用购买隧道 支付宝回调地址测试之后的学习计划 前言 最近一个项目用到了支付宝,但是本地调试的时候发现支付宝的回调地址需要在公网上能够访问到。为了更加方便地调试,就使用了natapp内网穿透,将回调…

FPGA语法相关知识合集

一.相关概念 1.四种结构说明语句 2.initial 与 always 的异同点 3.task 与 function 的3个不同点 4.task的语法结构(定义及调用) 5.function的语法结构(定义及调用) 6.function 的一个必须有和一个必须没有,使用规则 7.自动(递归)函数…

Win11+Modelsim SE-64 10.6d搭建UVM环境

1、添加源文件及tb文件 在目录下建立文件夹,将DUT和Testbench添加进去,文件夹内容如下所示: 2、以《UVM实战》中的例子做简单的示例: 2.1 设计文件 :dut.sv 功能很简单,即将接受到的数据原封不动发送出去…

指针与多维数组练习

例题一: 矩阵相乘 首先,如果你没学过线代的话,这边建议你去B站把宋浩的矩阵运算学了再来看题 如果有个矩阵A和一个矩阵B,当A的列数和B的行数相同时,生成一个新矩阵C,且C是通过矩阵乘法得来的 A[3][2]{3…

画中画视频剪辑:批量制作画中画视频,让视频更具吸引力和创意

在今天的视频制作环境中,画中画视频剪辑技术已经成为了一种主流。它不仅能增加视频的视觉吸引力,也可以提升观看体验。画中画视频剪辑是一种制作多个视频画面的技术,它可以将两个或更多的视频画面融合在一起,形成一个全新的视频。…

关于卓越服务的调研报告

NetSuite知识会发起的本次调研从2023年11月2日开始,到11月12日结束。16日已向参与调研的朋友邮件回复,感谢您的付出!今朝分享此报告,各位同学参考。 调研问题与反馈总结 问题1:您能想到哪些服务组织能够提供高满意度&…

GIS杂记(三):MaxEnt模型中的图像地理范围不匹配【全网最好的方法,没有之一】

图像地理范围不匹配问题解决方法 1. 问题描述2. 问题范例3. 问题解决4. 其他参考 1. 问题描述 一般在使用全国的的生物气候变量时,由于其地理范围一致,因此不会出现地理范围不匹配的问题。但是,当加入其他影响因子的时候,如海拔、…

vue之浏览器存储方法封装实例

我们在项目中通常会对缓存进行一些操作,为了便于全局调用,会对缓存的设置、获取及删除方法进行封装成一个工具类。 首先我们在src目录下创建一个plugins文件夹,在plugins下创建cache文件夹并创建index.js,代码如下: c…

Linux每日智囊-cat, more, less

每日分享三个Linux命令,悄悄培养读者的Linux技能。 cat 作用 在终端显示文件内容 cat命令允许创建单个或多个文件,查看文件的内容,连接文件并在终端或文件中重定向输出。 语法 cat [选项] 文件 参数: -n:显示行数&#xf…

Egress-TLS-Origination

目录 文章目录 目录本节实战1、出口网关TLS发起2、通过 egress 网关发起双向 TLS 连接关于我最后 本节实战 实战名称🚩 实战:Egress TLS Origination-2023.11.19(failed)🚩 实战:通过 egress 网关发起双向 TLS 连接-2023.11.19(测…