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

C++设计模式笔记(内附可运行代码示例)

持续更新, 欢迎关注.......

前言

设计目的

高内聚,低耦合

设计原则

1、开放封闭原则

类的改动是通过增加代码进行,而不是修改源代码。

2、单一职责原则

职责单一,对外只提供一种功能,引起类变化的原因都应该只有一个。

3、依赖倒置原则

依赖于抽象,不要依赖于具体实现,也就是针对接口编程。

4、接口隔离原则

一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中。

5、里氏替换原则

任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象功能。

6、优先使用组合而不是继承

7、迪米特法则

一个对象应该对其他对象尽可能少的了解,从而降低各个对象之间的耦合。

UML类图

参考UML类图几种关系的总结_在类图中,类与类-CSDN博客

创建型模式

单例模式

场景

- 在多个线程之间, 比如初始化一次 socket 资源; 比如 servlet 环境, 共享同一个资源或者
操作同一个对象

- 在整个程序空间使用全局变量, 共享资源
- 大规模系统中, 为了性能的考虑, 需要节省对象的创建时间等等。

核心要点

a) 构造函数私有化
b) 提供一个全局的静态方法(全局访问点)
c) 在类中定义一个静态指针, 指向本类的变量的静态变量指针

示例

懒汉式

构造延时到使用Instance时

#include <iostream>
using namespace std;
//懒汉式
class Singelton {
private:Singelton(){m_singer = NULL;m_count = 0;cout << "构造函数 Singelton ... do" << endl;}
public:static Singelton *getInstance(){if (m_singer == NULL ) //懒汉式: 1 每次获取实例都要判断 2 多线程会有问题{m_singer = new Singelton;}return m_singer;}static void printT(){cout << "m_count: " << m_count << endl;}
private:static Singelton *m_singer;static int m_count;
};Singelton *Singelton::m_singer = NULL; //懒汉式 并没有创建单例对象
int Singelton::m_count = 0;int main()
{cout << "演示 懒汉式" << endl;Singelton *p1 = Singelton::getInstance(); //只有在使用的时候, 才去创建对象。Singelton *p2 = Singelton::getInstance();if (p1 != p2) {cout << "不是同一个对象" << endl;} else {cout << "是同一个对象" << endl;}p1->printT();p2->printT();return 0;
}

运行结果:

演示 懒汉式
构造函数 Singelton ... do
是同一个对象
m_count: 0
m_count: 0
饿汉式

直接编译时就构造

#include <iostream>
using namespace std;class Singelton2
{private:Singelton2(){m_singer = NULL;m_count = 0;cout << "构造函数 Singelton ... do" << endl;}public:static Singelton2 *getInstance(){// if (m_singer == NULL )// {// m_singer = new Singelton2;// }return m_singer;}static void FreeInstance(){if (m_singer != NULL){delete m_singer;m_singer = NULL;m_count = 0;}}static void printT(){cout << "m_count: " << m_count << endl;}
private:static Singelton2 *m_singer;static int m_count;
};Singelton2 *Singelton2::m_singer = new Singelton2; //不管你创建不创建实例, 均把实例 new出来
int Singelton2::m_count = 0;int main()
{cout << "演示 饿汉式" << endl;Singelton2 *p1 = Singelton2::getInstance(); //只有在使用的时候, 才去创建对象。Singelton2 *p2 = Singelton2::getInstance();if (p1 != p2) {cout << "不是同一个对象" << endl;} else {cout << "是同一个对象" << endl;}p1->printT();p2->printT();Singelton2::FreeInstance();Singelton2::FreeInstance();return 0;
}

运行结果:

构造函数 Singelton ... do
演示 饿汉式
是同一个对象
m_count: 0
m_count: 0

简单工厂模式

场景

核心

1、工厂角色 --负责创建所有实例

工厂类是整个模式的关键,需要包含判断逻辑,能够根据外界给定的信息,决定创建哪个具体类的对象

2、抽象角色 --创建的所有对象的父类

3、具体产品角色 --具体实例对象

示例

工厂类里一定有选择逻辑

#include <iostream>
#include <cstring>
using namespace std;
//思想: 核心思想是用一个工厂, 来根据输入的条件产生不同的类, 然后根据不同类的 virtual函数得到不同的结果。
//元素分析:
//抽象产品类: 水果类
//具体的水果类: 香蕉类、 苹果类、 梨子
//优点 适用于不同情况创建不同的类时
//缺点 客户端必须要知道基类和工厂类, 耦合性差 增加一个产品, 需要修改工厂类
class Fruit {
public:virtual void getFruit() = 0;
protected:
private:
};class Banana : public Fruit {
public:virtual void getFruit(){cout<<"香蕉"<<endl;}
protected:
private:
};class Pear : public Fruit {
public:virtual void getFruit(){cout<<"梨子"<<endl;}
protected:
private:
};class Factory
{
public:static Fruit* Create(char *name){Fruit *tmp = NULL;if (strcmp(name, "pear") == 0){tmp = new Pear();} else if (strcmp(name, "banana") == 0) {tmp = new Banana();} else {return NULL;}return tmp;}
protected:
private:
};int main() {Fruit *pear = Factory::Create("pear");if (pear == NULL) {cout << "创建 pear 失败\n";}pear->getFruit();Fruit *banana = Factory::Create("banana");banana->getFruit();return 0;
}

 运行结果

梨子
香蕉

 工厂模式

场景

核心

1、抽象工厂(Creator) 角色                                                                                                  ---工厂方法模式的核心, 任何工厂类都必须实现这个接口。
2、具体工厂( Concrete Creator) 角色
---具体工厂类是抽象工厂的一个实现, 负责实例化产品对象。
3、抽象(Product) 角色
---工厂方法模式所创建的所有对象的父类, 它负责描述所有实例所共有的公共接口。
4、具体产品(Concrete Product) 角色
---工厂方法模式所创建的具体实例对象

和简单工厂模式不同:

a) 多了个抽象工厂类,每个具体工厂类统一来自抽象工厂

b) 添加新的产品对象时,只需添加一个具体对象和一个具体工厂

示例

1、抽象工厂:FruitFactory,具体工厂:BananaFactory、AppleFactory

2、抽象产品:Fruit,具体产品:Banana、Apple

3、main函数调用具体工厂时只是先把具体工厂创建出来,然后通过工厂的GetFruit创建具体对象

#include "iostream"
using namespace std;class Fruit
{
public:virtual void sayname(){cout<<"fruit\n";}
};class FruitFactory
{
public:virtual Fruit* getFruit(){return new Fruit();}
};
//香蕉
class Banana : public Fruit
{
public:virtual void sayname(){cout<<"Banana \n"<<endl;}
};
//香蕉工厂
class BananaFactory : public FruitFactory
{
public:virtual Fruit* getFruit(){return new Banana;}
};//苹果
class Apple : public Fruit
{
public:virtual void sayname(){cout<<"Apple \n"<<endl;}
};//苹果工厂
class AppleFactory : public FruitFactory
{
public:virtual Fruit* getFruit(){return new Apple;}
};int main()
{FruitFactory * ff = NULL;Fruit *fruit = NULL;//1 香蕉ff = new BananaFactory(); // 1、先创建具体工厂fruit = ff->getFruit(); // 2、通过具体工厂创建具体对象fruit->sayname();delete fruit;delete ff;//2 苹果ff = new AppleFactory();fruit = ff->getFruit();fruit->sayname();delete fruit;delete ff;cout<<"hello....\n";return 0;
}

运行结果:

Banana Apple hello....

抽象工厂模式

场景

可以一下生产一个产品族

核心

注意:上图的ConcreteFactory存在漏画问题,应该是CreateProductA(): AbStractProductA 和 CreateProductB(): AbStractProductB

1、抽象工厂角色

2、具体工厂角色

3、抽象产品角色

4、具体产品角色

示例

抽象工厂类:FruitFactory,具体工厂类:NorthFruitFactory、SourthFruitFactory;

抽象产品类:Fruit,具体产品类:SouthBanana/SouthApple/NorthBanana/NorthApple。

GetFruit切换成了GetApple、GetBanana,所以可以建立产品族。

#include "iostream"
using namespace std;class Fruit
{
public:virtual void sayname(){cout<<"fruit\n";}
};class FruitFactory
{
public:virtual Fruit* getApple(){return new Fruit();}virtual Fruit* getBanana(){return new Fruit();}
};
//南方香蕉
class SouthBanana : public Fruit
{
public:virtual void sayname(){cout<<"South Banana \n"<<endl;}
};//南方苹果
class SouthApple : public Fruit
{
public:virtual void sayname() {cout << "South Apple \n" << endl;}
};//北方香蕉
class NorthBanana : public Fruit
{
public:virtual void sayname(){cout<<"North Banana \n"<<endl;}
};//北方苹果
class NorthApple : public Fruit
{
public:virtual void sayname(){cout<<"North Apple \n"<<endl;}
};class SourthFruitFactory : public FruitFactory
{
public:virtual Fruit* getApple(){return new SouthApple();}virtual Fruit* getBanana(){return new SouthBanana();}
};
class NorthFruitFactory : public FruitFactory
{
public:virtual Fruit* getApple(){return new NorthApple();}virtual Fruit* getBanana(){return new NorthBanana();}
};
int main()
{FruitFactory * ff = NULL;Fruit *fruit = NULL;ff = new SourthFruitFactory(); // 1、建个南方工厂fruit = ff->getApple();        // 2、建立南方苹果fruit->sayname();fruit = ff->getBanana();       // 3、建立南方香蕉fruit->sayname();delete fruit;delete ff;ff = new NorthFruitFactory();fruit = ff->getApple();fruit->sayname();fruit = ff->getBanana();fruit->sayname();delete fruit;delete ff;cout<<"hello....\n";return 0;
}

运行结果

South Apple South Banana North Apple North Banana hello....

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Github 2024-07-25开源项目日报 Top10
  • ubuntu24.04 LTS安装BackupPC备份软件
  • docker compose 安装 kafka
  • ArduPilot开源代码之ROS2Humble+CartographerSLAM+SITL+Gazebo
  • reshape函数及MATLAB应用
  • sql查询优化小知识-01,非等值条件查询影响
  • Vue3基础语法
  • C#-了解ORM框架SqlSugar并快速使用(附工具)
  • c# 对接第三方接口实现签名
  • 记一次因敏感信息泄露而导致的越权+存储型XSS
  • 谷粒商城实战笔记-75-商品服务-API-品牌管理-品牌分类关联与级联更新
  • 微信小程序云开发订单微信支付与小票和标签打印的完整高效流程
  • 【C# 】Pipe管道通信使用
  • Java实现数据库图片上传(包含从数据库拿图片传递前端渲染)-图文详解
  • SSRF-labs-master靶场
  • ES6指北【2】—— 箭头函数
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 30天自制操作系统-2
  • es6(二):字符串的扩展
  • Js基础知识(四) - js运行原理与机制
  • js正则,这点儿就够用了
  • Markdown 语法简单说明
  • MaxCompute访问TableStore(OTS) 数据
  • nodejs调试方法
  • PHP面试之三:MySQL数据库
  • PHP那些事儿
  • scala基础语法(二)
  • Selenium实战教程系列(二)---元素定位
  • SpingCloudBus整合RabbitMQ
  • SQLServer插入数据
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • Yii源码解读-服务定位器(Service Locator)
  • 从tcpdump抓包看TCP/IP协议
  • 关于Flux,Vuex,Redux的思考
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​configparser --- 配置文件解析器​
  • ​Java并发新构件之Exchanger
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • # Redis 入门到精通(九)-- 主从复制(1)
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $.ajax()
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (1)常见O(n^2)排序算法解析
  • (js)循环条件满足时终止循环
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (四)React组件、useState、组件样式
  • (转)LINQ之路
  • (转)可以带来幸福的一本书