《C++设计模式》——创建型

前言

创建型为了创建东西才是有用的,创建型设计模式使用的场景:
1、创建一个东西;
2、可重复利用;
3、灵活性高,代码可因地制宜。

Factory Method(工厂模式)

工厂模式将目的将创建对象的具体过程屏蔽隔离起来,从而达到更高的灵活性,工厂模式可以分为三类:

  • 简单工厂模式(Simple Factory)
  • 工厂方法模式(Factory Method)
  • 抽象工厂模式(Abstract Factory)

这三种模式从上到下逐步抽象,并且更具一般性。《设计模式》一书中将工厂模式分为两类:工厂方法模式与抽象工厂模式。将简单工厂模式看为工厂方法模式的一种特例,两者归为一类。

Simple Factory(简单工厂)

主要用于创建对象。新添加类时,不会影响以前的系统代码。核心思想是用一个工厂来根据输入的条件产生不同的类,然后根据不同类的 virtual 函数得到不同的结果。
GOOD:适用于不同情况创建不同的类时
BUG:客户端必须要知道基类和工厂类,耦合性差
在这里插入图片描述

simpleFactory.h

#ifndef CLION_TEST_SIMPLEFACTORY_H
#define CLION_TEST_SIMPLEFACTORY_H//基类
class COperation {
public:int m_nFirst;int m_nSecond;virtual double GetResult() {double dResult = 0;return dResult;}
};//加法
class AddOperation : public COperation {
public:double GetResult() final {return m_nFirst + m_nSecond;}
};//减法
class SubOperation : public COperation {
public:double GetResult() final {return m_nFirst - m_nSecond;}
};//工厂类
class CCalculatorFactory {
public:static COperation *Create(char cOperator) {COperation *oper;switch (cOperator) {case '+':oper = new AddOperation();break;case '-':oper = new SubOperation();break;default:oper = new AddOperation();break;}return oper;}
};#endif //CLION_TEST_SIMPLEFACTORY_H

main.cpp

#include <iostream>
#include "simpleFactory.h"using namespace std;int main() {int a = 1;int b = 2;COperation * op=CCalculatorFactory::Create('-');op->m_nFirst=a;op->m_nSecond=b;cout<<op->GetResult()<<endl;return 0;
}

Factory Method(工厂方法)

GOOD:修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
一个产品对应一个工厂类。
在这里插入图片描述
factorymethod.h

#ifndef CLION_TEST_FACTORYMETHOD_H
#define CLION_TEST_FACTORYMETHOD_H#include <iostream>
#include <string>using namespace std;// 实例基类,相当于Product
class LeiFeng {
public:virtual void Sweep() {cout << "雷锋扫地" << endl;}
};// 学雷锋的大学生,相当于ConcreteProduct
class Student : public LeiFeng {
public:void Sweep() final {cout << "大学生扫地" << endl;}
};// 学雷锋的志愿者,相当于ConcreteProduct
class Volenter : public LeiFeng {
public:void Sweep() final {cout << "志愿者" << endl;}
};// 工厂基类 Creator
class LeiFengFactory {
public:virtual LeiFeng *CreateLeiFeng() {return new LeiFeng();}
};// 工厂具体类
class StudentFactory : public LeiFengFactory {
public:LeiFeng *CreateLeiFeng() final {return new Student();}
};class VolenterFactory : public LeiFengFactory {
public:LeiFeng* CreateLeiFeng() final {return new Volenter();}
};#endif //CLION_TEST_FACTORYMETHOD_H

main.cpp

#include "factorymethod.h"using namespace std;int main() {// 工厂方法LeiFengFactory *sf = new StudentFactory();LeiFeng *s = sf->CreateLeiFeng();s->Sweep();delete sf;delete s;sf = nullptr;s = nullptr;return 0;
}

Abstract Factory(抽象工厂)

GOOD:定义了一个创建一系列相关或相互依赖的接口,而无需指定它们的具体类。
用于交换产品系列,如 ACCESS­>SQL SERVER;
产品的具体类名被具体工厂的实现分离
在这里插入图片描述
abstractfactory.h

#ifndef CLION_TEST_ABSTRACTFACTORY_H
#define CLION_TEST_ABSTRACTFACTORY_H#include <iostream>using namespace std;// 用户抽象接口
class IUser {
public:virtual void GetUser() = 0;virtual void InsertUser() = 0;
};// 部门抽象接口
class IDepartment {
public:virtual void GetDepartment() = 0;virtual void InsertDepartment() = 0;
};// ACCESS用户
class CAccessUser : public IUser {
public:void GetUser() final {cout << "Access GetUser" << endl;}void InsertUser() final {cout << "Access InsertUser" << endl;}
};// ACCESS部门
class CAccessDepartment : public IDepartment {
public:void GetDepartment() final {cout << "Access GetDepartment" << endl;}void InsertDepartment() final {cout << "Access InsertDepartment" << endl;}
};// SQL用户
class CSqlUser : public IUser {
public:void GetUser() final {cout << "Sql User" << endl;}void InsertUser() final {cout << "Sql User" << endl;}
};// SQL部门类
class CSqlDepartment : public IDepartment {
public:void GetDepartment() final {cout << "sql getDepartment" << endl;}void InsertDepartment() final {cout << "sql insertdepartment" << endl;}
};// 抽象工厂
class IFactory {
public:virtual IUser *CreateUser() = 0;virtual IDepartment *CreateDepartment() = 0;
};// ACCESS工厂
class AccessFactory : public IFactory {
public:IUser *CreateUser() final {return new CAccessUser();}IDepartment *CreateDepartment() final {return new CAccessDepartment();}
};// SQL工厂
class SqlFactory : public IFactory {
public:IUser *CreateUser() final {return new CSqlUser();}IDepartment *CreateDepartment() final {return new CSqlDepartment();}
};#endif //CLION_TEST_ABSTRACTFACTORY_H

main.cpp

#include "abstractfactory.h"using namespace std;int main() {system("chcp 65001");// 抽象工厂模式///cout<<"SQL用户"<<endl;IFactory* factory = new SqlFactory();IUser* user = factory->CreateUser();IDepartment* department = factory->CreateDepartment();user->GetUser();department->GetDepartment();///cout<<"ACCESS用户"<<endl;factory = new AccessFactory();user = factory->CreateUser();department = factory->CreateDepartment();user->GetUser();department->GetDepartment();return 0;
}

Builder(建造者)

GOOD:在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用。
在这里插入图片描述

builder.h

#ifndef CLION_TEST_BUILDER_H
#define CLION_TEST_BUILDER_H#include <string>
#include <iostream>
#include <vector>using namespace std;// 最终的产品类
class Product {
private:vector<string> m_product;
public:void Add(string strtemp) {m_product.push_back(strtemp);}void Show() {for (auto p = m_product.begin(); p != m_product.end(); ++p) {cout << *p << endl;}}
};// 建设者基类
class Builder {
public:virtual void BuilderA() = 0;virtual void BuilderB() = 0;virtual Product *GetResult() = 0;
};// 第一种建造方式
class ConcreteBuilder1 : public Builder {
private:Product *m_proudct;
public:ConcreteBuilder1() {m_proudct = new Product();}void BuilderA() final {m_proudct->Add("one");}void BuilderB() final {m_proudct->Add("two");}Product *GetResult() final {return m_proudct;}
};// 第二种建造方式
class ConcreteBuilder2 : public Builder {
private:Product *m_proudct;
public:ConcreteBuilder2() {m_proudct = new Product();}void BuilderA() final {m_proudct->Add("A");}void BuilderB() final {m_proudct->Add("B");}Product *GetResult() final {return m_proudct;}
};// 指挥者类
class Direct {
public:void Construct(Builder *temp) {temp->BuilderA();temp->BuilderB();}
};#endif //CLION_TEST_BUILDER_H

main.cpp

#include "builder.h"
using namespace std;int main() {system("chcp 65001");// 建造者模式Direct *p = new Direct();Builder* b1 = new ConcreteBuilder1();Builder* b2 = new ConcreteBuilder2();p->Construct(b1); // 调用第一种方式Product* pb1 = b1->GetResult();pb1->Show();p->Construct(b2); // 调用第二种方式Product* pb2 = b2->GetResult();pb2->Show();return 0;
}

Prototype(原型)

GOOD:从一个对象再创建另外一个可定制的对象,而无需知道任何创建的细节。并能提高创建的性能。 说白了就 COPY 技术,把一个对象完整的 COPY 出一份。
注:此处书写的是浅拷贝,当需要复制的内容更改时不影响原先的内容,需要进行深拷贝,好奇地是原型模式直接使用拷贝赋值或拷贝构造函数不就可以了嘛。
在这里插入图片描述
prototype.h

#ifndef CLION_TEST_PROTOTYPE_H
#define CLION_TEST_PROTOTYPE_H#include <iostream>
#include <vector>
#include <string>using namespace std;// 抽象基类
class Prototype {
private:string m_strName;
public:Prototype(string strName) { m_strName = strName; }Prototype() { m_strName = ""; }void Show() {cout << m_strName << endl;}virtual Prototype *Clone() = 0;
};// class ConcretePrototype1
class ConcretePrototype1 : public Prototype {
public:ConcretePrototype1(string strName) : Prototype(strName) {}ConcretePrototype1() {}Prototype *Clone() final {ConcretePrototype1 *p = new ConcretePrototype1();*p = *this; // 复制对象return p;}
};// class ConcretePrototype2
class ConcretePrototype2 : public Prototype {
public:ConcretePrototype2(string strName) : Prototype(strName) {}ConcretePrototype2() {}Prototype *Clone() final {ConcretePrototype2 *p = new ConcretePrototype2();*p = *this; // 复制对象return p;}
};#endif //CLION_TEST_PROTOTYPE_H

main.cpp

#include <iostream>
#include "prototype.h"using namespace std;int main() {system("chcp 65001");// 客户端ConcretePrototype1* test1 = new ConcretePrototype1("小王");ConcretePrototype2* test2 = (ConcretePrototype2*)test1->Clone();test1->Show();test2->Show();return 0;
}

Singleton(单例)

后记

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go channel实践与源码探索(初始化、发送消息、接收消息、关闭)

文章目录 概要一、并发编程1.1、Actor模型1.2、CSP模型 二、Go Channel实践三、源码分析3.1、初始化3.2、发送消息3.3、接收消息3.4、关闭通道 总结 概要 通道&#xff08;Channel&#xff09;是Go语言提供的协程之间通信与同步的方式。我们知道在并发编程&#xff08;多进程、…

时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化

时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化 目录 时序分解 | MATLAB实现北方苍鹰优化算法NGO优化VMD信号分量可视化效果一览基本介绍程序设计参考资料 效果一览 基本介绍 北方苍鹰优化算法NGO优化VMD&#xff0c;对其分解层数&#xff0c;惩罚因子数做优化…

基于Python开发的玛丽大冒险小游戏(源码+可执行程序exe文件+程序配置说明书+程序使用说明书)

一、项目简介 本项目是一套基于Python开发的玛丽冒险小游戏程序&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Python学习者。 包含&#xff1a;项目源码、项目文档等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xf…

Alibaba(商品详情)API接口

为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个alibaba应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载alibaba API的SDK并掌握基本的API基础知识和调用 4&#xff09;利…

管理类联考——数学——汇总篇——知识点突破——应用题——交叉比例法/杠杆原理

读书笔记 甲有&#xff1a;x个a&#xff0c;乙有&#xff1a;y个b&#xff0c;甲乙的平均值为c&#xff0c;根据总数相等&#xff0c;得&#xff1a;axbyc(xy)&#xff0c;即ax-cxcy-by&#xff0c;则 x y c − b a − c \frac{x}{y}\frac{c-b}{a-c} yx​a−cc−b​ &#…

OpenCV(二十五):边缘检测(一)

目录 1.边缘检测原理 2.Sobel算子边缘检测 3.Scharr算子边缘检测 4.两种算子的生成getDerivKernels() 1.边缘检测原理 其原理是基于图像中灰度值的变化来捕捉图像中的边界和轮廓。梯度则表示了图像中像素强度变化的强弱和方向。 所以沿梯度方向找到有最大梯度值的像素&…

17-数据结构-查找-(顺序、折半、分块)

简介&#xff1a;查找&#xff0c;顾名思义&#xff0c;是我们处理数据时常用的操作之一。大概就是我们从表格中去搜索我们想要的东西&#xff0c;这个表格&#xff0c;就是所谓的查找表&#xff08;存储数据的表&#xff09;。而我们怎么设计查找&#xff0c;才可以让计算机更…

sqli-labs关卡之一(两种做法)

目录 一、布尔盲注(bool注入) 二、时间盲注(sleep注入) 一、布尔盲注(bool注入) 页面没有报错和回显信息&#xff0c;只会返回正常或者不正常的信息&#xff0c;这时候就可以用布尔盲注 布尔盲注原理是先将你查询结果的第一个字符转换为ascii码&#xff0c;再与后面的数字比较…

Redis带你深入学习数据类型set

目录 1、set 2、set相关命令 2.1、添加元素 sadd 2.2、获取元素 smembers 2.3、判断元素是否存在 sismember 2.4、获取set中元素数量 scard 2.5、删除元素spop、srem 2.6、移动元素smove 2.7、集合中相关命令&#xff1a;sinter、sinterstore、sunion、sunionstore、s…

mac电脑安装paste教程以及重新安装软件后不能使用解决方法

问题背景 mac电脑安装paste教程以及重新安装软件后不能使用解决方法。 mac电脑安装paste失败&#xff0c;安装好后还是无法使用&#xff0c;paste显示还是历史粘贴信息&#xff0c;导致无法使用。新 copy的内容也无法进入历史粘贴版里面。 笔者电脑配置信息&#xff1a;MacB…

【算法与数据结构】501、LeetCode二叉搜索树中的众数

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;根据前面几篇文章98、LeetCode验证二叉搜索树、530、LeetCode二叉搜索树的最小绝对差。我们知道二叉搜…

Boost搜索引擎

项目背景 先说一下什么是搜索引擎,很简单,就是我们平常使用的百度,我们把自己想要所有的内容输入进去,百度给我们返回相关的内容.百度一般给我们返回哪些内容呢?这里很简单,我们先来看一下. 搜索引擎基本原理 这里我们简单的说一下我们的搜索引擎的基本原理. 我们给服务器发…

Selenium - Tracy 小笔记2

selenium本身是一个自动化测试工具。 它可以让python代码调用浏览器。并获取到浏览器中加们可以利用selenium提供的各项功能。帮助我们完成数据的抓取。它容易被网站识别到&#xff0c;所以有些网站爬不到。 它没有逻辑&#xff0c;只有相应的函数&#xff0c;直接搜索即可 …

基于SSM的精品酒销售管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Linux平台如何实现采集音视频数据并注入轻量级RTSP服务?

技术背景 好多开发者&#xff0c;问我们最多的问题是&#xff0c;为什么要设计轻量级RTSP服务&#xff1f;轻量级RTSP服务&#xff0c;和RTSP服务有什么区别&#xff1f; 针对这个问题&#xff0c;我们的回答是&#xff1a;轻量级RTSP服务解决的核心痛点是避免用户或者开发者…

MSTP + Eth-Trunk配置实验 华为实验手册

1.1 实验介绍 1.1.1 关于本实验 以太网是当今现有局域网LAN&#xff08;Local Area Network&#xff09;采用的最通用的通信协议标准&#xff0c;以太网作为一种原理简单、便于实现同时又价格低廉的局域网技术已经成为业界的主流。 本实验主要介绍了LAN网络中的Eth-Trunk技术…

Jmeter系列-Jmeter面板介绍和常用配置(2)

Jmeter面板介绍 常用菜单栏 分布式运行相关的 选项&#xff0c;可以打开日志&#xff0c;修改语言、函数助手对话框&#xff0c;还有管理插件 常用的图标 从左到右依次 新建测试计划选择测试计划模板创建一个新的测试计划打开jmeter脚本保存jmeter脚本剪切复制粘贴展开目录…

《向量数据库指南》——向量数据库和关系型数据库的区别?

向量数据库和关系型数据库是两种不同类型的数据库系统,它们在数据模型、数据存储、查询操作等方面存在许多区别。以下是向量数据库和关系型数据库的主要区别: 1、数据模型: 向量数据库:向量数据库专门设计用于存储和查询向量数据,这些数据通常表示为数值向量或嵌入向量。向…

ssm实现折线统计图

​ 方法1&#xff1a;单张数据表中的数据图表生成 图表统计&#xff0c;查看部门人数统计这里实现的时单张表中的数据实现部门人数折线统计图展示。 <script type"text/javascript">// 利用AjAx来获取后台传入的数据&#xff08;Responsebody注解传入的&…

阿里云和腾讯云2核2G服务器价格和性能对比

2核2G云服务器可以选择阿里云服务器或腾讯云服务器&#xff0c;腾讯云轻量2核2G3M带宽服务器95元一年&#xff0c;阿里云轻量2核2G3M带宽优惠价108元一年&#xff0c;不只是轻量应用服务器&#xff0c;阿里云还可以选择ECS云服务器u1&#xff0c;腾讯云也可以选择CVM标准型S5云…