当前位置: 首页 > 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;



        

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Java 自定义注解 笔记总结(油管)
  • 【Go】通过反射解析对象tag信息,实现简易ORM
  • llama factory 训练 TensorBoard 可视化
  • 【C++】——Vector的模拟实现
  • Golang | Leetcode Golang题解之第324题摆动排序II
  • mysql如何储存大量数据,分库存分表的建议和看法
  • gbd的概念与常用指令
  • 【Linux基础】Linux基本指令(一)
  • 小米教你:2GB内存搞定20亿数据的高效算法
  • 【C++】vector 的模拟实现
  • 从0开始的算法(数据结构和算法)基础(七)
  • Unity Addressables bundle依赖查看和资源重复查看工具
  • linux 多进程搭建webserver
  • MinGW-w64编译安装Acise
  • 维吉尼亚密码加解密实现(python)
  • Hibernate最全面试题
  • Iterator 和 for...of 循环
  • Javascript 原型链
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • MobX
  • Nacos系列:Nacos的Java SDK使用
  • TypeScript实现数据结构(一)栈,队列,链表
  • vue-cli在webpack的配置文件探究
  • 安装python包到指定虚拟环境
  • 初识MongoDB分片
  • 每天一个设计模式之命令模式
  • 批量截取pdf文件
  • 如何进阶一名有竞争力的程序员?
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 王永庆:技术创新改变教育未来
  • 我的业余项目总结
  • 【干货分享】dos命令大全
  • 阿里云ACE认证之理解CDN技术
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • (C++17) optional的使用
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (每日一问)设计模式:设计模式的原则与分类——如何提升代码质量?
  • (三)uboot源码分析
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (小白学Java)Java简介和基本配置
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转载)(官方)UE4--图像编程----着色器开发
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net Core 微服务之Consul(三)-KV存储分布式锁
  • .NET 解决重复提交问题
  • .net通过类组装数据转换为json并且传递给对方接口
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @Documented注解的作用
  • []C/C++读取串口接收到的数据程序
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [4]CUDA中的向量计算与并行通信模式
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured