泛型产品注册模板类 + 单例工厂模板类
C++
#include <iostream>
#include <map>
/***********************/
// 基类 鞋子
class Shoes
{
public:
virtual void Show() = 0;
virtual ~Shoes() {}
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;
}
};
// 阿迪鞋子
class AdidasShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是阿迪球鞋,我的广告语:Impossible is nothing." << std::endl;
}
};
// 基类 衣服
class Clothe
{
public:
virtual void Show() = 0;
virtual ~Clothe() {}
};
// 优衣库衣服
class UniqloClothe : public Clothe
{
public:
void Show()
{
std::cout << "我是优衣库衣服,我的广告语:I am Uniqlo" << std::endl;
}
};
// 盗版衣服
class DaoBanClothe : public Clothe
{
public:
void Show()
{
std::cout << "我是盗版衣,我的广告语:想怎么盗版就怎么盗版。" << std::endl;
}
};
/**************************************/
// 基类,产品注册模板接口类
// 模板参数 ProductType_t 表示的类是产品抽象类
template <typename ProductType_t>
class IProductRegistrar
{
public:
// 获取产品对象抽象接口
virtual ProductType_t* CreateProduct() = 0;
protected:
// 禁止外部构造和虚构, 子类的"内部"的其他函数可以调用
IProductRegistrar() {}
virtual ~IProductRegistrar() {}
private:
// 禁止外部拷贝和赋值操作
IProductRegistrar(const IProductRegistrar&);
const IProductRegistrar& operator=(const IProductRegistrar&);
};
// 工厂模板类,用于获取和注册产品对象
// 模板参数 ProductType_t 表示的类是产品抽象类
template <typename ProductType_t>
class ProductFactory
{
public:
// 获取工厂单例,工厂的实例是唯一的
static ProductFactory<ProductType_t>& Instance()
{
static ProductFactory<ProductType_t> instance;
return instance;
}
// 产品注册
void RegisterProduct(IProductRegistrar<ProductType_t>* registrar, std::string name)
{
m_ProductRegistry[name] = registrar;
}
// 根据名字name,获取对应具体的产品对象
ProductType_t* GetProduct(std::string name)
{
// 从map找到已经注册过的产品,并返回产品对象
if (m_ProductRegistry.find(name) != m_ProductRegistry.end())
{
return m_ProductRegistry[name]->CreateProduct();
}
// 未注册的产品,则报错未找到
std::cout << "No product found for " << name << std::endl;
return NULL;
}
private:
// 禁止外部构造和虚构
ProductFactory() {}
~ProductFactory() {}
// 禁止外部拷贝和赋值操作
ProductFactory(const ProductFactory&);
const ProductFactory& operator=(const ProductFactory&);
// 保存注册过的产品,key:产品名字 , value:产品类型
std::map<std::string, IProductRegistrar<ProductType_t>*> m_ProductRegistry;
};
// 产品注册模板类,用于创建具体产品和从工厂里注册产品
// 模板参数 ProductType_t 表示的类是产品抽象类(基类),ProductImpl_t 表示的类是具体产品(产品种类的子类)
template <typename ProductType_t, typename ProductImpl_t>
class ProductRegistrar : public IProductRegistrar<ProductType_t>
{
public:
// 构造函数,用于注册产品到工厂,只能显示调用
explicit ProductRegistrar(std::string name)
{
// 通过工厂单例把产品注册到工厂
ProductFactory<ProductType_t>::Instance().RegisterProduct(this, name);
}
// 创建具体产品对象指针
ProductType_t* CreateProduct()
{
return new ProductImpl_t();
}
};
/***************************************************************/
int main()
{
// ========================== 生产耐克球鞋过程 ===========================//
// 注册产品种类为Shoes(基类),产品为NiKe(子类)到工厂,产品名为nike
ProductRegistrar<Shoes, NiKeShoes> nikeShoes("nike");
ProductRegistrar<Shoes, AdidasShoes> adidasShoes("adidas"); // 如果相同键值,会覆盖前面的。如果还是 nike,会用 adidas 的信息覆盖掉前面的。
// 从工厂获取产品种类为Shoes,名称为nike的产品对象
Shoes* pNiKeShoes = ProductFactory<Shoes>::Instance().GetProduct("nike");
Shoes* pAdidasShoes = ProductFactory<Shoes>::Instance().GetProduct("adidas");
// 显示产品的广告语
pNiKeShoes->Show();
pAdidasShoes->Show();
// 释放资源
if (pNiKeShoes)
{
delete pNiKeShoes;
}
if (pAdidasShoes != nullptr) {
delete pAdidasShoes;
pAdidasShoes = nullptr;
}
std::cout << std::endl;
// ========================== 生产优衣库衣服过程 ===========================//
// 注册产品种类为Clothe(基类),产品为UniqloClothe(子类)到工厂,产品名为uniqlo
ProductRegistrar<Clothe, UniqloClothe> uniqloCloth("uniqlo");
ProductRegistrar<Clothe, DaoBanClothe> daobanCloth("daoban");
// 从工厂获取产品种类为Shoes,名称为adidas的产品对象
Clothe* pUniqloClothe = ProductFactory<Clothe>::Instance().GetProduct("uniqlo");
Clothe* pDaobanClothe = ProductFactory<Clothe>::Instance().GetProduct("daoban");
// 显示产品的广告语
pUniqloClothe->Show();
pDaobanClothe->Show();
// 释放资源
if (pUniqloClothe)
{
delete pUniqloClothe;
}
if (pDaobanClothe != nullptr) {
delete pDaobanClothe;
pDaobanClothe = nullptr;
}
return 0;
}
输出:
我是耐克球鞋,我的广告语:Just do it
我是阿迪球鞋,我的广告语:Impossible is nothing.
我是优衣库衣服,我的广告语:I am Uniqlo
我是盗版衣,我的广告语:想怎么盗版就怎么盗版。
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2020-10-16 关于指针和数组的移动