创建型设计模式
一、设计模式介绍
1.设计模式是什么
2.设计模式怎么来的?
3.设计模式解决什么问题?
前提:具体需求既有稳定点又有变化点;
期待修改修改少量代码,就可以适应需求的变化;
4.设计模式基础
面向对象思想:封装、继承、多态;
设计原则;
5.设计原则有哪些?
5.1依赖倒置

5.2.开放封闭
5.3.面向接口
5.4.封装变化点
5.5.单一职责
5.6.里氏替换
5.7.接口隔离
5.8.组合优于继承
6.设计模式如何应用
6.1.明确目的:
6.2.步骤分析
该设计模式需要解决的问题(稳定点、变化点);
该设计模式的代码结构是什么;
符合哪些设计原则;
如何扩展代码;
联想应用场景;
二、设计模式
1.模板方法
1.1.定义
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。——《设计模式》
1.2.背景
某个平拍动物园,有一套固定的表演流程,但是其中有若干个表演子流程可创新替换,以尝试迭代更新表演流程;
1.3.要点
最常用的设计模式,子类可以复写父类子流程,使父类的骨架流程丰富;
反向控制流程的典型应用;
父类protected保护子类需要复写的子流程;这样子类的子流程只能父类来调用;
1.4.本质
通过固定算法骨架来约束子类的行为;
稳定点:算法骨架,基类保持不变;
变化点:子类产生变化,重写父类方法;
1.5.结构图
1.6.代码结构
基类中有骨架流程接口;
所有子流程对子类开放并且是虚函数;
多态使用方式;
1.7.代码
#include <iostream>
using namespace std;// 开闭
class ZooShow {
public:void Show() {// 如果子表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接进入下一个子表演流程if (Show0())PlayGame();Show1();Show2();Show3();}private:void PlayGame() {cout << "after Show0, then play game" << endl;}bool expired;// 对其他用户关闭,但是子类开放的
protected:virtual bool Show0() {cout << "show0" << endl;if (! expired) {return true;}return false;}virtual void Show2() {cout << "show2" << endl;}virtual void Show1() {}virtual void Show3() {}
};// 框架
// 模板方法模式
class ZooShowEx10 : public ZooShow {
protected:virtual void Show0() {if (! expired) {return true;}return false;}
}class ZooShowEx1 : public ZooShow {
protected:virtual bool Show0() {cout << "ZooShowEx1 show0" << endl;if (! expired) { // 里氏替换return true;}return false;}virtual void Show2(){cout << "show3" << endl;}
};class ZooShowEx2 : public ZooShow {
protected:virtual void Show1(){cout << "show1" << endl;}virtual void Show2(){cout << "show3" << endl;}
};class ZooShowEx3 : public ZooShow {
protected:virtual void Show1(){cout << "show1" << endl;}virtual void Show3(){cout << "show3" << endl;}virtual void Show4() {//}
};
/*
*/
int main () {ZooShow *zs = new ZooShowEx10; // 晚绑定还是早绑定// ZooShow *zs1 = new ZooShowEx1;// ZooShow *zs2 = new ZooShowEx2;zs->Show();return 0;
}
晚绑定:在编译时绑定;父类指针指向的子类对象会发生类型转换,变成基类对象。
早绑定:多态,运行时绑定。
多态组合:利用多态将原本耦合的基类和子类组合,只余下一个基类指针
1.8.符合那些设计原则
单一职责、开闭、依赖倒置(子类扩展时,需要依赖基类的虚函数实现;使用者只依赖接口)、封装变化点(protected)、接口隔离、最小知道原则。
2.观察者模式
2.1.定义
定义对象间的一种一对多(变化)的依赖关系,一边当一个对象(Subject)的状态发生变化时,所有依赖于它的对象都得到通知并自动更新。——《设计模式》GoF
2.2.背景
气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到两个不同的显示设备(A和B);
2.3.要点
观察者模式使得我们可以独立地改变目标和观察者,从而使二者之间的关系松耦合;
观察者自己决定是否订阅通知,目标对象并不关注谁订阅了;
观察者不要依赖通知顺序,目标对象也不知道通知顺序;
常用在基于事件的ui框架中,也是MVC的组成部分;
常用在分布式系统中,actor框架中;
2.4.本质
触发联动
2.5.结构图
2.6.代码结构
稳定点:“一”对“多”的依赖关系,“一”变化“多跟着变化”;
变化点:“多”增加、减少;
2.7.代码
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
//
class IDisplay {
public:virtual void Show(float temperature) = 0;virtual ~IDisplay() {}
};class DisplayA : public IDisplay {
public:virtual void Show(float temperature) {cout << "DisplayA Show" << endl;}
private:void jianyi();
};class DisplayB : public IDisplay{
public:virtual void Show(float temperature) {cout << "DisplayB Show" << endl;}
};class DisplayC : public IDisplay{
public:virtual void Show(float temperature) {cout << "DisplayC Show" << endl;}
};class DisplayD : public IDisplay{
public:virtual void Show(float temperature) {cout << "DisplayC Show" << endl;}
};class WeatherData {
};// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
class DataCenter {
public:void Attach(IDisplay * ob) {//}void Detach(IDisplay * ob) {//}void Notify() {float temper = CalcTemperature();for (auto &ob : obs) {ob->Show(temper);}}// 接口隔离
private:WeatherData * GetWeatherData();float CalcTemperature() {WeatherData * data = GetWeatherData();// ...float temper/* = */;return temper;}std::list<IDisplay*> obs;
};int main() {// 单例模式DataCenter *center = new DataCenter;// ... 某个模块IDisplay *da = new DisplayA();center->Attach(da);// ...IDisplay *db = new DisplayB();center->Attach(db);IDisplay *dc = new DisplayC();center->Attach(dc);center->Notify();//-----center->Detach(db);center->Notify();center->Notify();return 0;
}
3.策略模式
3.1.定义
定义一些列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。——《设计模式》
3.2.背景
某商场节假日固定促销活动,为了加大促销力度,现提升国庆节促销活动规格;
3.3.要点
策略模式提供了一系列可重用的算法,从而可以是的类型在运行时方便地根据需要在各个算法之间进行切换;
策略模式消除了条件判断语句;也就是在解耦合;
3.4.本质
分离算法,选择实现;
3.5.结构图
3.6.代码
class Context {};// 稳定点:抽象去解决它
// 变化点:扩展(继承和组合)去解决它
class ProStategy {
public:virtual double CalcPro(const Context &ctx) = 0;virtual ~ProStategy();
};
// cpp
class VAC_Spring : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};class VAC_Spring_v2 : public VAC_Spring {
public:virtual double CalcPro(const Context &ctx){//....}
};class VAC_worker : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};// cpp
class VAC_QiXi : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};
class VAC_QiXi1 : public VAC_QiXi {
public:virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_Wuyi : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_GuoQing : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};
class VAC_GuoQing2 : public VAC_GuoQing {
public:virtual double CalcPro(const Context &ctx){}
};class VAC_Shengdan : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};// 设计原则:接口隔离原则
// 组合、继承
// 组合基类指针
// 两种方法:1. 采用具体接口选择算法 2. 依赖注入
class Promotion {
public:Promotion(ProStategy *sss = nullptr) : s(sss){}~Promotion(){}void Choose(ProStategy *sss) {// 条件选择if (sss != nullptr) {s = sss;}}double CalcPromotion(const Context &ctx){if (s != nullptr) {return s->CalcPro(ctx);}return 0.0L;}
private:ProStategy *s;
};int main () {Context ctx;ProStategy *s = new VAC_QiXi1();Promotion *p = new Promotion(s);p->Choose(new VAC_GuoQing2());p->CalcPromotion(ctx);return 0;
}
相关文章:

创建型设计模式
一、设计模式介绍 1.设计模式是什么 设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案; 2.设计模式怎么来的? 满足设计原则后,慢慢迭代出来的。 3.设…...

仿iOS日历、飞书日历、Google日历的日模式
仿iOS日历、飞书日历、Google日历的日模式,24H内事件可自由上下拖动、自由拉伸。 以下是效果图: 具体实现比较简单,代码如下: import android.content.Context; import android.graphics.Canvas; import android.graphics.Color;…...

vuedraggable
官方文档:https://www.npmjs.com/package/vuedraggable 中文文档:http://www.itxst.com/vue-draggable/tutorial.html 案例下载地址: https://github.com/SortableJS/Vue.Draggable.git vuedraggablehttps://sortablejs.github.io/Vue.Dr…...

新手从事直播软件源码开发搭建经验与技巧
如果从YY或六间房的PC秀场直播间系统软件算起,直播软件已经在国内风云了至少10年了,站在用户角度提到直播系统大家基本都知道核心功能有开直播刷礼物等,那么如果站在直播软件源码开发搭建的技术角度去看呢?是不是要从需求调研分析…...
相机不动,机构动作----Hands Eyes
最近在研究 手眼标定,发现大家都需付费,搞啥子,说好的开源。。。 以相机在上固定不动,机械手为 EPSON_Robot 为例,详细的一步一步实例操作指引 EPSON_Robot 的192.168.0.1 2004 Server 详细操作步骤 1. 启动程序 运…...

Scala的导入
//导入 //(1) 创建包:在src上右键,新建软件包 //(2)填写包名:小写 //(3)在包上右键,创建类。自动加入包名 //(4)导入。import 包名.类名 //导入多个类 //import jh.yuanlixueyuan.bigdata.scala03.{A,B,C} //导入包下的所有的类 /…...
vue2中父子组件传值案例总结
在 Vue 2 中,父子组件之间的传值是通过 props 和事件来实现的。下面是详细的解释和总结: 1. 父组件向子组件传值 父组件可以通过 props 向子组件传递数据。以下是一个简单的示例: 父组件 (Parent.vue) <template><div><h1…...
功能篇:springboot中实现文件导出
### Spring Boot 中实现文件导出功能 #### 概述 在现代Web应用程序中,文件导出是一个常见的需求,允许用户将数据以特定格式(如CSV、Excel、PDF等)下载到本地。本文将详细介绍如何使用Spring Boot实现文件导出功能,并…...
Redis客户端(Jedis、RedisTemplate、Redisson)
1. 简介 Redis作为一个当下很火热的非关系型数据库,Java从业人员基本都离不开对Redis的使用。在Java程序中该数据库,需要借助于市面上的开源客户端,如Jedis、Spring Data Redis、Redisson,它们可以作为操作Redis非关系型数据库的桥…...

Mybatis中SQL的执行过程
文章目录 Mybatis 框架SQL执行过程数据库操作映射方式SQL的执行过程- SQL解析- SQL参数映射- SQL预编译- SQL执行- 结果映射- 事务处理- 缓存处理- 日志记录与监控 扩展#与$的区别- $ 符号- # 符号总结示例 Mybatis SQL分类- 动态 SQL- 静态 SQL静态SQL和动态SQL选择${}、#{}与…...

【数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
目录😋 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:编写一个程序实现顺序栈的基本运算。 相关知识 为了完成本关任务,你需要掌握: 初始化栈、销毁栈、判断栈是否为空、进栈、出栈、取…...

【论文阅读】PRIS: Practical robust invertible network for image steganography
内容简介 论文标题:PRIS: Practical robust invertible network for image steganography 作者:Hang Yang, Yitian Xu∗, Xuhua Liu∗, Xiaodong Ma∗ 发表时间:2024年4月11日 Engineering Applications of Artificial Intelligence 关键…...
在Linux桌面系统普及化方面的一些建议
在推动Linux桌面系统普及化的过程中,可以考虑以下几个方案和策略: 用户友好性改进: 界面设计:提升用户界面的美观性和易用性,使其更接近或超越主流操作系统的用户体验。软件兼容性:确保常用软件(…...

LLM - 多模态大模型的开源评估工具 VLMEvalKit 部署与测试 教程
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144353087 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 VLMEva…...

数据结构(Queue队列)
前言: 在计算机科学中,数据结构是构建高效算法和程序的基础,而队列(Queue)作为一种经典的线性数据结构,具有重要的地位。与栈(Stack)不同,队列遵循“先进先出”…...
Qt 图形框架下图形拖动后位置跳动问题
在使用Qt 的图形框架QGraphicsScene,QGraphicsView实现图形显示时。遇到一个很棘手的BUG。 使用的图形是自定义的QGraphicsObject的子类。 现象是将图形添加到画布上之后,用鼠标拖动图形,图形能正常改变位置,当再次用鼠标点击图…...

【Linux篇】走进Linux — 开启开源操作系统之旅
文章目录 初识Linux一.Linux的起源与发展二.Linux的特点三.Linux的应用四.Linux的发行版本 Linux环境搭建一.Linux环境的搭建方式二.购买云服务器三.使用XShell远程登陆到Linux 初识Linux 一.Linux的起源与发展 1.初始动机: Linux是一个功能强大的开源操作系统&am…...

如何利用DBeaver配置连接MongoDB和人大金仓数据库
最近根据国产化要求,需要使用国产数据库,但习惯使用DBeaver连接各种成熟的商业或开源数据库。因此,就想着如何继续基于该工具,连接MongoDB和人大金仓数据库,查了半天很多地方说法不统一,所以自己就简单整理…...

Android 车载虚拟化底层技术-Kernel 5.10 -Android12(multi-cards)技术实现
详细代码实现见 Android Display Graphics系列文章-汇总Android Display Graphics系列文章-汇总 Android Display Graphics系列文章-汇总 Android Display Graphics系列文章-汇总 本文主要包括部分: 一、Android12的Kernel 5.10版本 1.1 Kernel 5…...

Qt之点击鼠标右键创建菜单栏使用(六)
Qt开发 系列文章 - menu(六) 目录 前言 一、示例演示 二、菜单栏 1.MenuBar 2.Menu 总结 前言 QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏(menubar)、多个工具栏(toolbars)、一个状态栏(status…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...