C++简单工厂模式的学习
我们先从最常见的C++类的一个实现开始说起,
class API
{
public:
virtual test(std::string s)=0;
protected:
API(){};
};
class ImpleOne :public API {
public:
void test(string s) override {
std::cout << "现在是One在执行 " << s<<std::endl;
}
}; int main(void)
{
API * pApi=new ImpleOne();
pApi->test();
return;
}
这样的代码就会破坏我们面向对象的封装性,因为调用者会知道API和IMPLEONE的存在。
怎么样完成高内聚,低耦合这个要求那?
那就用一下我们的简单工厂模式,在头文件中
#include<iostream>
#include<string>
#include<map>
//建立函数指针
typedef void* (*Constructor)(); //创建一个工厂.
class CObjectFactory
{
public:
//注册对应的类添加到容器中
static void RegsiterClass(std::string classname, Constructor constructor)
{
constructors()[classname] = constructor;
}
//创建一个类的对象并返回
static void* CreateObject(const std::string ClassName)
{
Constructor constructor = nullptr;
if (constructors().find(ClassName) != constructors().end())
{
constructor = constructors().find(ClassName)->second;
}
if (constructor == nullptr)
{
return nullptr;
}
return (*constructor)();
}
private:
//返回一个容器
static std::map<std::string, Constructor>& constructors()
{
static std::map<std::string, Constructor> instance;
return instance;
} }; //注册我们的类的宏定义
#define REG_CLASS(class_name) \
class class_name##Helper{ \
public: \
class_name##Helper(){ \
CObjectFactory::RegsiterClass(#class_name,class_name##Helper::CreateObjFunc); \
}; \
static void*CreateObjFunc() \
{ \
return new class_name; \
} \
};\
static class_name##Helper class_name##helper; //加入static是指只在头文件中有效。
然后就是如何调用这个简单工厂
//在这里可以通过读取配置文件,或者直接修改REG_CLASS和CreateObject中的字符串,就可以完成对这个类的改变,或者更新 ,并不影响后面代码的更改。
REG_CLASS(ImpleOne)
class AUTOFACTORY
{
public:
std::shared_ptr<Api> CreateAPI()
{ std::shared_ptr<API> Apipointer(static_cast<API*>(CObjectFactory::CreateObject("ImpleOne")));
return Apipointer;
}
}
int main(void)
{
std::shared_ptr<Api> testpoint(AUTOFACTORY::CreateAPI());
testpoint->test("我不是你爸爸!");
return;
}
总结一下:我们可以通过创建一个类作为工厂提供我们所需要的类,并且通过一个辅助注册的类,使我们需要的类注册到我们的工厂里面,我们的调用者可以不通过知道我们类中的具体实现,就可以获取到他们所需的类,并且完好的实现了类的封装性.我们在以后修改或者替换我们的类的时候就不会影响调用者的代码。
C++简单工厂模式的学习的更多相关文章
- C#简单工厂模式(学习Learning hard讲解笔记)
原味地址http://www.cnblogs.com/zhili/p/SimpleFactory.html 简单工厂模式通俗的理解就是用户与工厂的关系,用户用的东西,工厂来生成,责任明确. 就像大神展 ...
- 派生类&简单工厂模式
派生类&简单工厂模式 git链接: Operation3.1.1 题目描述的代码部分的解释 首先是声明一个Rand类作为父类,然后两个子类RandNumber类和RandOperation类, ...
- Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)
jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...
- 设计模式之简单工厂模式(C#语言描述)
严格意义上来说,简单工厂模式并不属于GoF的23种设计模式,但是它是学习其他工厂模式的基础和前提条件.理解了简单工厂模式,学习工厂方法模式和抽象工厂模式会比较容易一些. 简单工厂模式的定义 定义一个工 ...
- 【2016-10-17】【坚持学习】【Day8】【简单工厂模式】
今天学习简单工厂模式, 结构 一个抽象产品 多个具体产品 一个工厂类,通过传入参数,new出不同的产品 代码: abstract class Product { //所有产品类的公共业务方法 publ ...
- Java设计模式学习记录-简单工厂模式、工厂方法模式
前言 之前介绍了设计模式的原则和分类等概述.今天开启设计模式的学习,首先要介绍的就是工厂模式,在介绍工厂模式前会先介绍一下简单工厂模式,这样由浅入深来介绍. 简单工厂模式 做法:创建一个工厂(方法或类 ...
- 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- 学习设计模式第二十七 - GoF之外简单工厂模式
示例代码来自<深入浅出设计模式>和<大话设计模式> 概述 简单工厂模式又被称为静态工厂模式,属于类的创建型模式.其实质是由一个工厂类根据传入的参量,动态决定应该创建出哪一个产品 ...
随机推荐
- 2021.12.15 P2328 [SCOI2005]超级格雷码(找规律填空)
2021.12.15 P2328 [SCOI2005]超级格雷码(找规律填空) https://www.luogu.com.cn/problem/P2328 题意: 输出n位B进制的格雷码. 分析: ...
- [源码解析] TensorFlow 分布式之 MirroredStrategy
[源码解析] TensorFlow 分布式之 MirroredStrategy 目录 [源码解析] TensorFlow 分布式之 MirroredStrategy 1. 设计&思路 1.1 ...
- python学习-Day18
目录 今日内容详细 模块 循环导入问题 判断文件类型 py文件可以被分为两种类型 内置变量 __ name __ 模块的查找顺序 验证先从内存空间中查找 验证再从内置模块中查找 验证sys.path ...
- SpringBoot 如何进行参数校验
为什么需要参数校验 在日常的接口开发中,为了防止非法参数对业务造成影响,经常需要对接口的参数进行校验,例如登录的时候需要校验用户名和密码是否为空,添加用户的时候校验用户邮箱地址.手机号码格式是否正确. ...
- 研讨会回放视频:如何提升Jenkins能力,使其成为真正的DevOps平台
"如何实现集中管理.灵活高效的CI/CD"在线研讨会精彩分享 演讲嘉宾:杨海涛 在2022年3月29日举办的"如何实现集中管理.灵活高效的CI/CD"在线研讨会 ...
- HCNP Routing&Switching之链路聚合
前文我们了解了MSTP相关话题,回顾清参考https://www.cnblogs.com/qiuhom-1874/p/16268682.html:今天我们来聊一聊链路聚合相关话题: 链路聚合是链路高可 ...
- Docker部署mysql 5.7
Docker部署mysql 5.7 准备工作 在CentOS或者Linux创建部署目录,用于存放容器的配置和MySQL数据:目的是当重装或者升级容器时,配置文件和数据不会丢失.执行以下命令: a.创建 ...
- linux篇-linux 主从配置
1准备两台服务器 一台是192.168.118.128 一台是192.168.118.129 2主服务器配置 192.168.118.128 修改my.cnf文件 server-id=1 log-bi ...
- cpulimit-限制CPU速率
CPULimit是一个简单的程序,它可以限制指定进程的CPU百分比. 1.安装依赖 root@localhost:~# apt-get -y install git 2.从GitHUB中克隆源码到本地 ...
- 源码解读etcd heartbeat,election timeout之间的拉锯
转一个我在知乎上回答的有关raft election timeout/ heartbeat interval 的回答吧. 答:准确来讲: election是timeout,而heartbeat 是in ...