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

设计模式 由浅入深(待完结)

一、设计模式是什么?

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

二、设计模式有哪些?

1. 观察者模式

        定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

1.1. 背景

        气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到多个不同的显示终端(A 、B、C)。

1.2. 伪代码

#include <list>
#include <algorithm>
#include <iostream>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;}
};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) {obs.emplace_back(ob);}void Detach(IDisplay * ob) {if(obs.empty()){return;}for(auto it = obs.begin(); it != obs.end(); ++it){if(*it == ob){obs.erase(it);return;}}}void Notify() {float temper = CalcTemperature();for (auto iter : obs) {iter->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->Attach(dd);center->Notify();return 0;
}

2. 策略模式

        定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。

2.1 背景

        某商场节假日有固定促销活动,为了加大促销力度,现提升国庆节促销活动规格;

2.2 伪代码

class Context {};class ProStategy {
public:virtual double CalcPro(const Context &ctx) = 0;virtual ~ProStategy(); 
};class VAC_Spring : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};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){}
};class VAC_Wuyi : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};class VAC_GuoQing : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};class VAC_Shengdan : public ProStategy {
public:virtual double CalcPro(const Context &ctx){}
};class Promotion {
public:Promotion(ProStategy *sss) : s(sss){}~Promotion(){}double CalcPromotion(const Context &ctx){return s->CalcPro(ctx);}
private:ProStategy *s;
};int main () {Context ctx;ProStategy *s = new VAC_QiXi1();Promotion *p = new Promotion(s);p->CalcPromotion(ctx);return 0;
}

3. 单例模式

        保证一个类仅有一个实例,并提供一个该实例的全局访问点。

3.1 代码实现

版本一 

#include <bits/stdc++.h>class Singleton
{
public:static Singleton *getInstance(){if (nullptr == _instance){_instance = new Singleton();}return _instance;}~Singleton(){if (_instance){delete _instance;_instance = nullptr;}}private:Singleton() {}Singleton(const Singelton &) = delete;Singleton &operator=(const Singleton &) = delete;Singleton(Singleton &&) == delete;Singleton &operator=(Singleton &&) = delete;private:static Singleton *_instance;
};Singleton *Singleton::_instance = nullptr;

版本二  

#include <bits/stdc++.h>class Singleton
{
public:static Singleton *getInstance(){if (nullptr == _instance){_instance = new Singleton();atexit(destroy); // 存在线程安全问题}return _instance;}private:static void destroy(){if (_instance){delete _instance;_instance = nullptr;}}Singleton() {}~Singleton() {}Singleton(const Singelton &) = delete;Singleton &operator=(const Singleton &) = delete;Singleton(Singleton &&) == delete;Singleton &operator=(Singleton &&) = delete;private:static Singleton *_instance;
};Singleton *Singleton::_instance = nullptr;

版本三 饿汉模式 解决线程不安全

#include <bits/stdc++.h>class Singleton
{
public:static Singleton *getInstance(){if (nullptr == _instance){_instance = new Singleton();atexit(destroy); // 存在线程安全问题}return _instance;}private:static void destroy(){if (_instance){delete _instance;_instance = nullptr;}}Singleton() {}~Singleton() {}Singleton(const Singelton &) = delete;Singleton &operator=(const Singleton &) = delete;Singleton(Singleton &&) == delete;Singleton &operator=(Singleton &&) = delete;private:static Singleton *_instance;
};Singleton *Singleton::_instance = Singleton::getinstance(); //饿汉模式

版本四 懒汉模式(饱汉模式)加锁解决线程不安全

#include <bits/stdc++.h>class Singleton
{
public:static Singleton *getInstance(){std::lock_guard<std::mutex> lock(_mutex);  //加锁if (nullptr == _instance){_instance = new Singleton();atexit(destroy); }return _instance;}private:static void destroy(){if (_instance){delete _instance;_instance = nullptr;}}Singleton() {}~Singleton() {}Singleton(const Singelton &) = delete;Singleton &operator=(const Singleton &) = delete;Singleton(Singleton &&) == delete;Singleton &operator=(Singleton &&) = delete;private:static Singleton *_instance;static std::mutex _mutex;
};Singleton *Singleton::_instance = nullptr;  //懒汉模式std::mutex Singleton::_mutex;



        

相关文章:

设计模式 由浅入深(待完结)

一、设计模式是什么&#xff1f; 设计模式是指在软件开发中&#xff0c;经过验证的&#xff0c;用于解决在特定环境下&#xff0c;重复出现的&#xff0c;特定问题的解决方案。 二、设计模式有哪些&#xff1f; 1. 观察者模式 定义对象间的一种一对多&#xff08;变化&#x…...

(第34天)645、最大二叉树

目录 645、最大二叉树题目描述思路代码 645、最大二叉树 题目描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大…...

Python知识点:如何使用Paramiko进行SSH连接与操作

使用Paramiko进行SSH连接与操作可以分为以下几个步骤&#xff1a; 安装Paramiko&#xff1a; 首先需要安装Paramiko库&#xff0c;可以使用pip进行安装&#xff1a; pip install paramiko建立SSH连接&#xff1a; 使用Paramiko连接远程服务器&#xff0c;需要提供服务器的地址、…...

代码随想录算法训练营第六天(一)|242.有效的字母异位词

LeetCode 242 有效的字母异位词 题目&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 示例 1: 输入: s "anagram&q…...

数据结构 | 考研代码题之顺序表 | 1 查找L中值为e的数据元素若找到则返回其下标,若找不到则返回-1

文章目录 1 题目2 题解 1 题目 假设有一个顺序表 L&#xff0c;其存储的所有数据元素均为不重复的正数&#xff0c;查找L中值为e的数据元素&#xff0c;若找到则返回其下标&#xff0c;若找不到则返回-1。 2 题解 C语言代码&#xff1a; /*假设有一个顺序表 L&#xff0c;其…...

RLVF:避免过度泛化地从口头反馈中学习

人工智能咨询培训老师叶梓 转载标明出处 大模型在不同行业和个人中的广泛应用要求模型能够根据具体的用户反馈进行调整或定制&#xff0c;以满足细微的要求和偏好。虽然通过高层次的口头反馈来指定模型调整非常方便&#xff0c;例如“在给老板起草电子邮件时不要使用表情符号”…...

设计原则与思想-从项目实战中学习设计模式

文章目录 开源项目通过剖析Java JDK源码学习灵活应用设计模式1. 单例模式(Singleton Pattern)示例:`java.lang.Runtime`2. 工厂模式(Factory Pattern)示例:`java.util.Date`3. 观察者模式(Observer Pattern)示例:`java.util.Observable` 和 `java.util.Observer`4. 适…...

python中的类属性、实例属性、类方法、实例方法和静态方法

1. 类属性(类变量)和实例属性(实例变量) 在python中&#xff0c;类中的属性就是定义在类中的变量&#xff0c;简称成员变量&#xff1b;类中的行为就是定义在类中的方法&#xff0c;简称成员方法。成员变量又可分为类变量和实例变量&#xff0c;或者分为类属性和实例属性。成员…...

A股继续底部震荡,探底是否能成功?

真心的给股民朋友提个醒&#xff0c;不管你胆大还是胆怯&#xff0c;盘面上出现了1个反常信号&#xff0c;一起来看看&#xff1a; 1、今天两市低开高走&#xff0c;开始筑底了&#xff0c;任何一个主力&#xff0c;都是在无人问津的熊市布局&#xff0c;而在人声鼎沸的牛市离场…...

NPDP考前怎么复习?NPDP200问PDF版来啦~

距离NPDP下半年考试还有4个月的时间&#xff0c;现在正是备考的黄金期。 以下复习建议~ 01.制定详细计划 首先&#xff0c;根据考试大纲&#xff0c;可以将内容划分为几个模块&#xff0c;如新产品开发流程、市场研究、产品规划等&#xff0c;并为每个模块设定学习目标和时间…...

ajax图书管理项目

bootstrap弹框 不离开当前页面&#xff0c;显示单独内容&#xff0c;让用户操作 功能&#xff1a;不离开当前页面&#xff0c;显示单独内容&#xff0c;供用户操作步骤&#xff1a; 1.引入bootstrap.css和bootstrap.js …...

深入理解 Java SPI - 概念、原理、应用

零、前言 在当今互联网时代&#xff0c;应用程序越来越复杂&#xff0c;对于我们开发人员来说&#xff0c;如何实现高效的组件化和模块化已经成为了一个重要的问题。而 Java SPI&#xff08;Service Provider Interface&#xff09;机制&#xff0c;作为一种基于接口的服务发现…...

JavaScript - 判断数组中是否包含某个的元素的几种方式

目录​​​​​​​​​​​​​​ 1. 使用 includes 方法 2. 使用 indexOf 方法 3. 使用 find 方法 4. 使用 some 方法 5. 使用 filter 方法 6. 使用 every 方法​​​​​​​ 应该算是前端开发过程中比较常用的基本操作&#xff0c;话不多说&#xff0c;看代码。 1. 使…...

如何用AI颠覆企业未来:从大企业到中小型企业的实战攻略

如何用AI颠覆企业未来&#xff1a;从大企业到中小型企业的实战攻略 AI大佬经验分享&#xff1a;聊聊企业定制化AI需求和应用场景 今天想跟大家聊聊我在AI领域的一些经验和见解&#xff0c;希望能对大家有所启发。最近&#xff0c;不少企业都对AI很感兴趣&#xff0c;我也经常…...

Linux磁盘管理_LVM逻辑卷_SWAP交换分区_Centos-LVM格式磁盘扩容

目录 一、基本磁盘管理1.1 创建分区1.2 创建文件系统1.3 挂载mount1.4 查看挂载信息1.5 重启失效解决方式 二、逻辑卷LVM2.1 LVM2.2 创建LVM2.3 扩大卷组VG2.4 命令汇总 三、交换分区SWAP管理3.1 SWAP3.2 查看swap3.3 增加交换分区 四、Centos调整分区&#xff0c;在线调整分区…...

C++ 函数模板和类模板

参考视频&#xff1a;C类模板_哔哩哔哩_bilibili 遗留问题&#xff1a;编译器怎么处理函数模板和类模板 目录 一、为什么会有函数模版&#xff1f;函数模板是为了解决什么问题&#xff1f; 二、函数模板的概念 三、函数模版的使用 四、函数模板的特化 五、类模板的概念 …...

安卓Termux系统设备安装内网穿透工具实现远程使用SFTP传输文件

文章目录 前言1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 前言 本教程主要介绍如何在安卓 Termux 系统中使用 SFTP 文件传输&#xff0c;并结合cpolar内网穿透工具生成公网地址&#xff0c;轻松实现无公网IP环境远程传输&#xf…...

文件属性获取

1、getpwuid函数 #include <stdio.h> #include <sys/types.h> #include <pwd.h> int main(int argc, char *argv[]) {uid_t uid 1000;struct passwd * pw getpwuid(uid);printf("name:%s gid:%d info:%s wd:%s shell:%s\n",pw->pw_name,pw-&g…...

C:冒泡排序

1、冒泡排序介绍&#xff1a; 冒泡排序的核心思想就是&#xff1a;两两相邻的元素进行比较。 先用一个例子来帮助大家理解一下冒泡排序的算法是怎们进行的 有一排高矮不同的人站成一列&#xff0c;要按照从矮到高的顺序重新排队。 冒泡排序的方法就是&#xff0c;从第一个人…...

探秘C# LINQ元素运算:原理阐释与实践指南

文章目录 一、LINQ元素运算符概述二. ElementAt 和 ElementAtOrDefault三. First 和 FirstOrDefault四. Last 和 LastOrDefault五. Single 和 SingleOrDefault六. Where 和 Select七、实际应用场景示例总结 LINQ&#xff08;Language-Integrated Query&#xff09;是C#中强大且…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...