设计模式基础知识以及典型设计模式总结(上)

1. 基础

1. 什么是设计模式?

设计模式是指在软件开发中,经过验证的,用于解决在特定环境下重复出现的特定问题的解决方案。

简单的说,设计模式是解决问题的固定套路。

慎用设计模式。

2. 设计模式是怎么来的?

满足设计原则后,慢慢迭代出来的。

3. 设计模式解决了什么问题?

前提:具体需求既有稳定点,又有变化点。

目的:期望修改少量的代码,就可以适应需求的变化。

比喻:整洁的房间,有一只好动的猫,怎么保持房间的整洁?把猫关在笼子里。

4. 设计模式基础

1. 面向对象的特性
  • 封装:隐藏实现细节,实现模块化
  • 继承:无需修改原有类的情况下,实现对功能的扩展
  • 多态:静态多态:函数重载、模板。动态多态:虚函数动态绑定。
2. 面向对象设计的原则
  1. 依赖倒置。高层模块不应该依赖底层模块,两者都应该依赖抽象。抽象不应该依赖具体实现,具体实现应该依赖于抽象。
    请添加图片描述
  2. 开放封闭。一个类应该对扩展(组合和继承)开放,对修改关闭。
  3. 面向接口。
    • 不将变量类型声明为某个特定的具体类,而是声明为一个接口
    • 这样客户程序就无需知道对象的具体类型,只需要知道对象所具有的接口
    • 从而减少系统中各部分的依赖关系,实现“高内聚、松耦合”的类型设计方案
  4. 封装变化点。将需求中的稳定点和变化点分离,使用扩展来封装变化点。
  5. 单一职责。一个类应该仅有一个引起它变化的原因,即一个类应该只负责一个职责或功能。
  6. 里氏替换。子类型必须能够替换它的父类型。要求子类覆盖父类实现时,必须保证职责和功能的一致性。
  7. 接口隔离。不应强迫客户端依赖它们不需要的接口,即应该将庞大、臃肿的接口拆分成多个更小、更专一的接口,使得每个接口只包含客户端所需要的方法。
  8. 组合优于继承。继承耦合度高,组合耦合度低。
  9. 最小知道原则。

5. 如何学习设计模式?

1. 目的

在尽量少的修改原有代码基础上,来适应未来需求的变化。

2. 学习步骤
  1. 该设计模式解决了什么问题?–> 稳定点、变化点

  2. 该设计模式的代码结构?

  3. 符合那些设计原则?–> 写符合设计原则的代码

  4. 如何在上面扩展代码?

  5. 该设计模式有哪些典型应用场景?

2. 模板方法——类行为型模式

1. 定义

在父类中定义处理流程的框架,在子类中实现具体处理的模式。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特性。

2. 解决的问题

稳定点:算法骨架

变化点:子流程需要变化

当一个操作大体流程是稳定的,而其中某些步骤的实现会发生变化时,可以使用模板方法。

3. 代码结构
  • 基类中有骨架流程接口
  • 所有子流程对子类开放并且是虚函数
  • 多态的使用方式
4. 符合哪些设计原则
  • 单一职责
  • 开闭原则
  • 依赖倒置
  • 封装变化点
  • 接口隔离
  • 最小知道原则
5. 如何扩展
  • 实现子类继承基类,覆写子流程
  • 通过多态调用方式调用
6. 实例

请添加图片描述

上图中,AbstractDisplay类中定义了display方法,在该方法中依次调用了open、print、close这3个方法,虽然这3个方法都已经在AbstractDisplay中被声明了,但是都没有实体的抽象方法。这里,调用抽象方法的display方法就是模板方法,它定义了算法的处理流程框架,而具体的步骤实现由子类完成。

class AbstractDisplay
{
public:
    // 模板方法
    void display()
    {
        // 算法流程框架
        open();
		for (int i = 0; i < 5; ++i)
        {
            print();
        }
        close();
    }
    
protected:
    // 保护子类要覆写的子流程,这样子类的子流程只能由父类调用
    virtual void open() = 0;
    virtual void print() = 0;
    virtual void close() = 0;
};

class CharDisplay : public AbstractDisplay
{
protected:
    void open() override;
    void print() override;
    void close() override;
};

class StringDisplay : public AbstraceDisplay
{
protected:
    void open() override;
    void print() override;
    void close() override;
};

3. 观察者模式——对象行为型模式

1. 定义

定义了对象间的一种一对多的依赖关系,当一个对象(subject)的状态发生变化时,所有依赖于他的对象(Observers)都得到通知,并自动更新。本质是“触发联动”。

2. 解决的问题

稳定点:一对多的依赖关系,一变化,多要跟着变化

变化点:“多”增加,“多”减少

3. 代码结构
  • 一个Subject抽象类,作为观察对象,定义了注册观察者和删除观察者的方法。
  • 多个ConcreteSubject类,具体的观察对象,当自身状态发生变化后,他会通知所有已经注册的Observer角色。
  • 一个Observer抽象类,负责接受来自Subject角色的状态变化的通知。
  • 多个ConcreteObserver类,是具体的观察者。
4. 符合哪些设计原则
  • 面向接口编程
  • 接口隔离:类与类的依赖建立在接口上面;
  • 封装变化点:attach, detach
5. 如何扩展
  • 继承实现接口
  • 调用attach, detach
6. 实例

在这里插入图片描述

class Observer;

// Subject抽象类
class NumberGenerator
{
public:
    void addObserver(Observer *);
    void deleteObserver(Observer *);
    
    virtual int getNumber() = 0;
    virtual void execute() = 0;
    
private:
    std::set<Observer *> observers;
};

// Observer接口
class Observer
{
public:
    virtual void update(NumberGenerator *) = 0;
};

// 具体Subject类
class RandomNumberGenerator : public NumberGenerator
{
public:
    int getNumber() override;
    void execute() override;
    
private:
    int number;
};

// 具体Observer类
class DigitObserver : public Observer
{
public:
    void update(NumberGenerator *generator) override;
};

class GraphObserver : public Observer
{
public:
    void update(NumberGenerator *generator) override;
}

int main(int argc, const char *argv[])
{
    NumberGenerator generator = new RandomNumberGenerator;
    Observer observer1 = new DigitObserver;
    Observer observer2 = new GraphObserver;
    generator.addObserver(observer1);
    generator.addObserver(observer2);
    generator.execute();
    delete generator1;
    delete observer1;
    delete observer2;
}

4. 策略模式——对象行为模式

1. 定义

​ **定义一系列算法,把他们一个个封装起来,并使其可相互替换。**该模式使得算法可独立与客户程序进行变化。

​ 消除if_else。

​ 稳定点:抽象去解决它

​ 变化点:扩展去解决它

2. 解决了什么问题

​ 稳定点:客户程序与算法的调用关系

​ 变化点:新加算法;算法内容改变

3. 代码结构
  • Strategy接口
  • ConcreteStrategy类
4. 符合哪些设计原则
  • 接口隔离
    • 依赖注入,通过一个接口解决两个类的依赖。
5. 如何扩展
  • 定义新的具体类实现Strategy接口
6. 实例

在这里插入图片描述

5. 责任链——对象行为模式

1. 定义

**将多个对象组成一条职责链,然后按照它们在职责链上的顺序一个一个地找出到底应该谁来负责处理。**使用Chain of Responsibility模式可以弱化“请求方”和“处理方”之间的关联关系,让双方各自都成为可独立复用的组件。

2. 解决了什么问题

稳定点:处理请求的对象被组织为一个职责链;请求的处理方式。

变化点:对象的数量、顺序、具体每个对象的处理方式。

3. 代码结构
  • Handler(处理者),定义了处理请求的接口,如果不能处理,则传给下一个处理者。
  • ConcreteHandler(具体的处理者),实现处理请求的接口。
  • Client(请求者),向第一个ConcreteHandler角色发送请求的角色。

在这里插入图片描述

4. 符合哪些设计原则
  • 依赖倒置
  • 接口隔离
  • 开放封闭
  • 单一职责
5. 如何扩展
  • 定义新的类实现Handler接口
  • 通过指定具体Handler的next属性指定下一个处理者。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity3D学习FPS游戏(4)重力模拟和角色跳跃

前言&#xff1a;前面两篇文章&#xff0c;已经实现了角色的移动和视角转动&#xff0c;但是角色并没有办法跳跃&#xff0c;有时候还会随着视角移动跑到天上。这是因为缺少重力系统&#xff0c;本篇将实现重力和角色跳跃功能。觉得有帮助的话可以点赞收藏支持一下&#xff01;…

fmql之Linux RTC

模拟i2c&#xff0c;连接rtc芯片。 dts&#xff1a; /{ // 根节点i2c_gpio: i2c-gpio {#address-cells <1>;#size-cells <0>;compatible "i2c-gpio";// MIO56-SDA, MIO55-SCL // 引脚编号gpios <&portc 2 0&portc 1 0 >;i2c-gp…

Unity3D学习FPS游戏(2)简单场景、玩家移动控制

前言&#xff1a;上一篇的时候&#xff0c;我们已经导入了官方fps的素材&#xff0c;并且对三维模型有了一定了解。接下来我们要构建一个简单的场景让玩家能够有地方移动&#xff0c;然后写一个简单的玩家移动控制。 简单场景和玩家移动 简单场景玩家移动控制玩家模型视野-摄像…

单细胞配色效果模拟器 | 简陋版(已有颜色数组)

目的&#xff1a;假设你有一组颜色了&#xff0c;怎么模拟查看它们在单细胞DimPlot中的美学效果呢&#xff1f;要足够快&#xff0c;还要尽可能有模拟效果。 1. 尝试1: 随机矩阵&#xff0c;真的UMAP降维后绘图&#xff08;失败&#xff09; 造一个随机矩阵&#xff0c;使用S…

华为鸿蒙HarmonyOS应用开发者高级认证视频及题库答案

华为鸿蒙开发者高级认证的学习资料 1、课程内容涵盖HarmonyOS系统介绍、DevEco Studio工具使用、UI设计与开发、Ability设计与开发、分布式特性、原子化服务卡片以及应用发布等。每个实验都与课程相匹配&#xff0c;帮助加深理解并掌握技能 2、学习视频资料 华为HarmonyOS开发…

全能大模型GPT-4o体验和接入教程

GPT-4o体验和接入教程 前言一、原生API二、Python LangchainSpring AI总结 前言 Open AI发布了产品GPT-4o&#xff0c;o表示"omni"&#xff0c;全能的意思。 GPT-4o可以实时对音频、视觉和文本进行推理&#xff0c;响应时间平均为 320 毫秒&#xff0c;和人类之间对…

动态规划 —— 斐波那契数列模型-解码方法

1. 解码方法 题目链接&#xff1a; 91. 解码方法 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/decode-ways/description/ 2. 题目解析 1. 对字母A - Z进行编码1-26 2. 11106可以解码为1-1-10-6或者11-10-6, 但是11-1-06不能解码 3. 0n不能解码 4. …

微知-Lecroy力科的PCIe协议分析仪型号命名规则(PCIe代,金手指lanes数量)

文章目录 要点主要型号命名规则各代主要产品图片Summit M616 协议分析仪/训练器Summit T516 分析仪Summit T416 分析仪Summit T3-16分析仪Summit T28 分析仪 综述 要点 LeCroy(力科)成立于1964年&#xff0c;是一家专业生产示波器厂家。在美国纽约。一直把重点放在研制改善生产…

【Linux】线程池详解及其基本架构与单例模式实现

目录 1.关于线程池的基本理论 1.1.线程池是什么&#xff1f; 1.2.线程池的应用场景&#xff1a; 2.线程池的基本架构 2.1.线程容器 2.2.任务队列 2.3.线程函数&#xff08;HandlerTask&#xff09; 2.4.线程唤醒机制 3.添加单例模式 3.1.单例模式是什么&…

【Canvas与图标】六色彩虹圆角六边形图标

【成图】 120*120的png图标 以下是各种大小图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>六色彩虹圆角六边形…

总裁主题CeoMax-Pro主题7.6开心版

激活方式&#xff1a; 1.授权接口源码ceotheme-auth-api.zip搭建一个站点&#xff0c;绑定www.ceotheme.com域名&#xff0c;并配置任意一个域名的 SSL 证书。 2.在 hosts 中添加&#xff1a;127.0.0.1 www.ceotheme.com 3.上传class-wp-http.php到wp-includes目录&#xff…

Java案例——屏蔽信息

首先这次的案例需要用到substring方法&#xff0c;先了解一下&#xff1a; 首先我们来加密一下电话号码&#xff1b; package String; public class Demo_06 {public static void main(String[] args) {// 定义一个电话号码字符串String phoneNumber"13111112598"…

亚信安全DeepSecurity中标知名寿险机构云主机安全项目

近日&#xff0c;亚信安全DeepSecurity成功中标国内知名寿险机构的云主机安全项目。亚信安全凭借在云主机安全防护领域的突出技术优势&#xff0c;结合安全运营的能力&#xff0c;以“实战化”为指导&#xff0c;为用户提供无惧威胁攻击、无忧安全运营的一站式云安全体系&#…

unity中GameObject介绍

在 Unity 中&#xff0c;Cube和Sphere等基本几何体是 Unity 引擎的内置预制体&#xff08;Prefabs&#xff09;&#xff0c;它们属于 Unity 中的GameObject 系统&#xff0c;可以在 Unity 的 Hierarchy 视图或 Scene 视图中右键点击&#xff0c;然后在弹出的菜单中选择 3D Obje…

模型训练识别手写数字(二)

模型训练识别手写数字&#xff08;一&#xff09;使用手写数字图像进行模型测试 一、生成手写数字图像 1. 导入所需库 import cv2 import numpy as np import oscv2用于计算机视觉操作。 numpy用于处理数组和图像数据。 os用于文件和目录操作。 2. 初始化画布 canvas np.z…

多线程——线程的状态

线程状态的意义 ‌线程状态的意义在于描述线程在执行过程中的不同阶段和条件&#xff0c;帮助开发者更好地管理和调度线程资源。 线程的多种状态 线程的状态是一个枚举类型&#xff08;Thread.State&#xff09;&#xff0c;可以通过线程名.getState&#xff08;&#xff09…

(二十一)、Docker 部署 Minikube 使用可视化管理工具 Kuboard

文章目录 1、介绍docker 运行 minikube 集群节点&#xff08;kube-apiserver &#xff09;无法被直接访问的问题Kuboard 需要访问到 k8s 集群的kube-apiserver 2、安装 Kuboard2.1、k8s 集群节点可以被外部直接访问的情况2.1.1、下载镜像2.1.2、运行 deployment.yml2.1.3、访问…

滑动窗口子串

文章目录 滑动窗口一、无重复字符的最长子串二、找到字符串中所有字母异位词 子串三、和为 K 的子数组四、滑动窗口最大值五、最小覆盖子串 滑动窗口 一、无重复字符的最长子串 题目链接 &#xff08;方法一&#xff1a;暴力枚举&#xff09; &#xff08;方法二&#xff…

机器学习—Logistic回归算法

目录 一、基本概念二、决策边界三、损失函数四、交叉熵&#xff08;CrossEntropy&#xff09;损失函数1、二分类问题的交叉熵损失函数2、多分类问题的交叉熵损失函数3、交叉熵损失函数的特点4、交叉熵损失函数的应用 五、模型参数求解六、Logistic函数的应用及优缺点1、应用场景…

【开源免费】基于SpringBoot+Vue.JS在线文档管理系统(JAVA毕业设计)

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…