模板工厂
针对工厂方法模式封装成模板工厂类,那么这样在新增产品时,是不需要新增具体的工厂类,减少了代码的编写量。
// 基类 鞋子
class Shoes
{
public:
virtual void Show() = 0;
virtual ~Shoes() {}
};
// 耐克鞋子
class NiKeShoes : public Shoes
{
public:
void Show()
{
std::cout << "我是耐克球鞋,我的广告语:Just do it" << 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;
}
};
AbstractFactory为抽象模板工厂类,其中模板参数:AbstractProduc_t 产品抽象类,如Shoes、Clothe ConcreteFactory为具体模板工厂类,其中模板参数:AbstractProduct_t 产品抽象类(如Shoes、Clothe),ConcreteProduct_t 产品具体类(如NiKeShoes、UniqloClothe)
// 抽象模板工厂类
// 模板参数:AbstractProduct_t 产品抽象类
template <class AbstractProduct_t>
class AbstractFactory
{
public:
virtual AbstractProduct_t *CreateProduct() = 0;
virtual ~AbstractFactory() {}
};
// 具体模板工厂类
// 模板参数:AbstractProduct_t 产品抽象类,ConcreteProduct_t 产品具体类
template <class AbstractProduct_t, class ConcreteProduct_t>
class ConcreteFactory : public AbstractFactory<AbstractProduct_t>
{
public:
AbstractProduct_t *CreateProduct()
{
return new ConcreteProduct_t();
}
};
主函数,根据不同类型的产品,构造对应的产品的工厂对象,便可通过对应产品的工厂对象创建具体的产品对象。
int main()
{
// 构造耐克鞋的工厂对象
ConcreteFactory<Shoes, NiKeShoes> nikeFactory;
// 创建耐克鞋对象
Shoes *pNiKeShoes = nikeFactory.CreateProduct();
// 打印耐克鞋广告语
pNiKeShoes->Show();
// 构造优衣库衣服的工厂对象
ConcreteFactory<Clothe, UniqloClothe> uniqloFactory;
// 创建优衣库衣服对象
Clothe *pUniqloClothe = uniqloFactory.CreateProduct();
// 打印优衣库广告语
pUniqloClothe->Show();
// 释放资源
delete pNiKeShoes;
pNiKeShoes = NULL;
delete pUniqloClothe;
pUniqloClothe = NULL;
return 0;
}
产品注册模板类+单例工厂模板类
模板工厂虽然在新增产品的时候,不需要新增具体的工厂类,但是缺少一个可以统一随时随地获取指定的产品对象的类。产品的注册对象可以用std::map的方式保存,通过key-valve的方式可以轻松简单的获取对应的产品对象实例。<br /> IProductRegistrar为产品注册抽象类,模板参数 ProductType_t 表示的类是产品抽象类(如Shoes、Clothe)。提供了产品对象创建的纯虚函数CreateProduct。<br /> ProductFactory为工厂模板类,模板参数 ProductType_t 表示的类是产品抽象类(如Shoes、Clothe)。用于保存注册产品对象到std::map中和获取对应的产品对象。<br /> ProductRegistrar为产品注册模板类,模板参数 ProductType_t 表示的类是产品抽象类(如Shoes、Clothe),ProductImpl_t 表示的类是具体产品(如NikeShoes、UniqloClothe)。用于注册产品到工厂类和创建产品实例对象。
// 基类,产品注册模板接口类
// 模板参数 ProductType_t 表示的类是产品抽象类
template <class 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 <class 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 <class ProductType_t, class 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");
// 从工厂获取产品种类为Shoes,名称为nike的产品对象
Shoes *pNiKeShoes = ProductFactory<Shoes>::Instance().GetProduct("nike");
// 显示产品的广告语
pNiKeShoes->Show();
// 释放资源
if (pNiKeShoes)
{
delete pNiKeShoes;
}
// ========================== 生产优衣库衣服过程 ===========================//
// 注册产品种类为Clothe(基类),产品为UniqloClothe(子类)到工厂,产品名为uniqlo
ProductRegistrar<Clothe, UniqloClothe> adidasShoes("uniqlo");
// 从工厂获取产品种类为Shoes,名称为adidas的产品对象
Clothe *pUniqloClothe = ProductFactory<Clothe>::Instance().GetProduct("uniqlo");
// 显示产品的广告语
pUniqloClothe->Show();
// 释放资源
if (pUniqloClothe)
{
delete pUniqloClothe;
}
return 0;
}
工厂模式代码模板
这里作者给出一个基于工厂模式的代码模板,该模板中包含有注册,注销,获取状态等操作。同时该代码非常清晰,适合二次开发。
#pragma once
#include <map>
#include <functional>
template <class IdentifierType, class ProductType>
class DefaultFactoryError
{
public:
class Exception : public std::exception
{
public:
Exception(const IdentifierType& unkownId)
:unknownId_(unkownId){}
const char* what() const noexcept override
{
return "Unknown object type passed to Factory";
}
const IdentifierType GetId()
{
return unknownId_;
}
private:
IdentifierType unknownId_;
};
protected:
ProductType* OnUnknownType(const IdentifierType& id)
{
throw Exception(id);
}
};
template
<
class AbstractProduct,
class IdentifierType,
class ProductCreator = std::function<AbstractProduct*(void)>,
template<typename, class>
class FactoryErrorPolicy = DefaultFactoryError
>
class Factory
: public FactoryErrorPolicy<IdentifierType, AbstractProduct>
{
public:
bool Register(const IdentifierType& id, ProductCreator functor)
{
return associations_.insert(std::make_pair(id, functor)).second;
}
bool Unregister(const IdentifierType& id)
{
return associations_.erase(id);
}
AbstractProduct* CreateObject(const IdentifierType& id)
{
typename std::map<IdentifierType, ProductCreator>::const_iterator i = associations_.find(id);
if(i != associations_.end())
{
return (i->second)();
}
return this->OnUnknownType(id);
}
private:
std::map<IdentifierType, ProductCreator> associations_;
};
主函数调用,可动态扩展调用方法
#include <iostream>
#include <typeinfo>
#include "factory.h"
class Shap
{
public:
virtual ~Shap() {}
virtual void Rote(const float) = 0;
};
class Box : public Shap
{
public:
void Rote(const float angle)
{
std::cout << angle << std::endl;
}
};
int main(int argc, char **argv)
{
try
{
Factory<Shap, std::string> factory;
std::cout << typeid(Box).name() << std::endl;
// https://blog.csdn.net/qq_35587463/article/details/105054277
// 通过lamba返回一个Shap的类指针,内部为Box类
std::cout << factory.Register(typeid(Box).name(), []() -> Shap * { return new Box; }) << std::endl;
std::cout << factory.Unregister(typeid(Box).name()) << std::endl;
std::cout << factory.CreateObject(typeid(Box).name()) << std::endl;
}
catch (const std::exception &e)
{
std::cout << e.what() << std::endl;
}
return 0;
}