《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.mzph.cn/news/75256.shtml

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

相关文章

三维模型3DTile格式轻量化压缩处理工具常用几款软件介绍

三维模型3DTile格式轻量化压缩处理工具常用几款软件介绍 三维模型3DTile格式的轻量化处理旨在减少模型的存储空间和提高渲染性能。以下是一些推荐的工具软件&#xff0c;可以用于实现这个目的&#xff1a; MeshLab&#xff1a;MeshLab是一个开源的三维模型处理软件&#xff0c…

RBTree(红黑树)模拟实现(插入)

目录 红黑树的性质 红黑树的模拟插入 叔叔存在且为红色 叔叔不存在 旋转情况​​​​​​​ 叔叔存在且为黑色 总结 插入实现 节点 插入逻辑 左单旋 右单旋 红黑树是一颗平衡搜索二叉树&#xff0c;但是红黑树并不像 AVL 树一样是高度平衡二叉树&#xff0c;任意一…

自动化运维——ansible (五十二) (01)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、概述 1.1 为什么要用自动化运维软件 1.2 自动化运维 1.3 自动化运维要注意的方面 1.4 自动化运维主要关注的方面 1.5 常见的开源自动化运维软件 1.6 自动化运维软件…

华为OD机试 - 单词接龙 - 数据结构map、list (Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、输入示例1、输入&#xff1a;2、输出3、说明 五、解题思路1、核心思想&#xff1a;2、核心算法是构建一个map&#xff1a; 六、Java算法源码七、效果展示1、输入2、输出3、说明4、没有移除后再次拼接的情况&#xff0c;改…

Vue中实现3D得球自动旋转

具体实现 安装echarts 在终端下安装echarts npm install -D echarts 安装echarts-gl 在终端下安装echarts-gl npm install -D echarts-gl earth3D组件 earth3D.vue <template><div class"globe3d-earth-container" ><div class"globe3d-earth&qu…

CK_Label-V23货架标签(电池版本)接口文档

查询标签信息接口 接口类型&#xff1a;POST, 参数格式&#xff1a;json array 链接形式&#xff1a; http://localhost/wms/associate/getTagsMsg 代码形式&#xff1a; { url : http://localhost/wms/associate/getTagsMsg, requestMethed : GET, requestParameter :…

AKF拆分原则

在分布式软件环境下&#xff0c;为了保障分布式架构的可靠性、可扩展、高性能&#xff0c;通常会通过集群、扩容、数据分治等思想来实现&#xff0c;比如很多中间件的使用Redis、ZK、Kafka等&#xff0c;都可以通过这种设计思想来提高系统架构吞吐量。AKF是一个系统化的拓展思想…

苹果电脑快捷键集合

苹果电脑Windows系统下的ALT键是组合键。苹果电脑键盘左下角的Fnoption是Windows的alt键。同时按下两个键是ALT键的功能。在非组合状态下&#xff0c;单独按Option键。 补充&#xff1a; 1. 按controlalt&#xff08;选项&#xff09;delete 启动任务管理器。 2. Option-Del…

Mysql数据库之常用SQL语句及事务学习总结

数据库介绍 几个常见的缩写&#xff1a; DB&#xff1a;数据库。全称&#xff1a;DataBase。DBMS&#xff1a;数据库管理系统。全称&#xff1a;DataBase Management System。DBS&#xff1a;数据库系统。全称&#xff1a;DataBase System。DBA&#xff1a;数据库管理员。全称…

初识Nacos

前言 Nacos是一个用于微服务架构下的服务发现和配置管理以及服务管理的综合解决方案&#xff08;官网介绍&#xff09;&#xff0c;这里的服务发现其实就是注册中心&#xff0c;配置管理就是配置中心&#xff0c;而服务管理是二者的综合&#xff1b; Nacos特性 1.服务发现与…

什么是Linux

什么是Linux&#xff1f; 不知道大家是什么时候开始接触Linux&#xff0c;我记得我是大三的时候&#xff0c;那时候通过国嵌、韦东山的教学视频&#xff0c;跟着搭bootloader&#xff0c;修改内核&#xff0c;制作根文件系统&#xff0c;一步步&#xff0c;视频真的很简单&…

两性养生网站源码 生活类减肥网站源码 健康网模板源码 支持QQ登录和百度主动推送

本套模板非常适合生活类&#xff0c;两性类&#xff0c;减肥类等等类型的网站&#xff0c;这类型网站比较好做流量&#xff0c;因为客户群体众多&#xff0c; 可以自行改内容为其他类型网站模板总体非常简洁漂亮&#xff0c;配色合理&#xff0c;视觉舒服&#xff0c;并且配合…

HarmonyOS实现几种常见图片点击效果

一. 样例介绍 HarmonyOS提供了常用的图片、图片帧动画播放器组件&#xff0c;开发者可以根据实际场景和开发需求&#xff0c;实现不同的界面交互效果&#xff0c;包括&#xff1a;点击阴影效果、点击切换状态、点击动画效果、点击切换动效。 相关概念 image组件&#xff1a;图片…

IP175LLF基本参数和引脚图

特性 宽工作温度范围IP175LLF(0C至70C) IP175LLFI(-40C至85C)内置5个MAC和4个PHY 每个端口可配置为10base-t、100Base-TX 最多2K个MAC地址支持自极性10Mbps 汽车MDI-MDIX 支持1个MII/RMII端口Layer2-4多字段分类器 支持8-MultiField输入支持交通政策支持多字段过滤器 支…

静态链表处理

静态链表是指使用数组来表示节点。在C中&#xff0c;可以使用数组来创建静态列表&#xff0c;其中每个元素都有固定的位置和索引。可以通过下标寻址的方式来访问和操作列表中的元素。 单向列表&#xff1a; struct linkednode{int data;int next; }node[N]; 双向链表&#x…

K8S1.23.6版本详细安装教程以及错误解决方案(包括前置环境,使用部署工具kubeadm来引导集群)

准备工作&#xff08;来自官方文档&#xff09; 一台兼容的 Linux 主机。Kubernetes 项目为基于 Debian 和 Red Hat 的 Linux 发行版以及一些不提供包管理器的发行版提供通用的指令。每台机器 2 GB 或更多的 RAM&#xff08;如果少于这个数字将会影响你应用的运行内存&#xf…

HJ23 删除字符串中出现次数最少的字符

描述 实现删除字符串中出现次数最少的字符&#xff0c;若出现次数最少的字符有多个&#xff0c;则把出现次数最少的字符都删除。输出删除这些单词后的字符串&#xff0c;字符串中其它字符保持原来的顺序。 数据范围&#xff1a;输入的字符串长度满足 1≤n≤20 &#xff0c;保…

vue使用wangEditor

vue版本2.0&#xff1b;editor5.1.23版本&#xff1b;editor-for-vue&#xff1a;1.0.2版本 api文档入口 效果图 点击查看如何封装 安装步骤入口 npm install wangeditor/editor --savenpm install wangeditor/editor-for-vue --save代码&#xff08;未封装过的&#xff09;…

Layui快速入门之第三节栅格布局

目录 一&#xff1a;栅格布局的基本概念 二&#xff1a;栅格布局规则 三&#xff1a;始终等比例水平排列案例 四&#xff1a;响应式规则 五&#xff1a;移动设备、桌面端的组合响应式展现案例 六&#xff1a;移动设备、平板、桌面端的复杂组合响应式展现案例 七&#xf…

day35 线程

程序&#xff1a;是为了完成特定的任务&#xff0c;用某种语言编写的一组有序指令的集合&#xff0c;是一段静态的代码 进程&#xff1a;是程序的一次执行过程 线程&#xff1a;线程是进程中的一个执行单元 线程是调度和执行的单位 处理器和线程间的关系 创建线程(重点) 创建…