C++设计模式之模板工厂模式

  • 工厂模式一般分为简单工厂模式,工厂方法模式,抽象工厂模式,不过今天我介绍的是由模板实现的工厂模式,可以实现产品类自动注册到对应的工厂类,完全解耦,并且提供工厂单例访问。
  • fantory.h
#pragma once

#include <map>
#include <string>

//产品工具抽象类
template<class AbstractProduct>
class AbstractProductTool
{
public:
	virtual AbstractProduct* creatProduct() = 0;
protected:
	AbstractProductTool(){}
	~AbstractProductTool(){}
};

//工厂模板类
template<class AbstractProduct>
class ProductFactory
{
public:
	static ProductFactory<AbstractProduct> &instance() {
		static ProductFactory<AbstractProduct> factory;
		return factory;
	}

	void registerProduct(const std::string &name, AbstractProductTool<AbstractProduct>* adsProductTool) {
		m_registerProductMap[name] = adsProductTool;
	}

	AbstractProduct* createProduct(const std::string &name) {
		if (m_registerProductMap.find(name) != m_registerProductMap.end())
			return m_registerProductMap[name]->creatProduct();
		else
			return nullptr;
	}

private:
	ProductFactory(){}
	ProductFactory(const ProductFactory&){}
	ProductFactory& operator=(const ProductFactory&){}

	std::map<std::string, AbstractProductTool<AbstractProduct>* > m_registerProductMap;
};

//具体产品工具类
template<class AbstractProduct, class ConcreteProduct>
class ConcreteProductTool :public AbstractProductTool<AbstractProduct>
{
public:
	explicit ConcreteProductTool(const std::string& name) {
		ProductFactory<AbstractProduct>::instance().registerProduct(name, this);
	}

	AbstractProduct* creatProduct() override {
		return new ConcreteProduct();
	}
};

//利用全局静态变量的初始化特性实现产品类的自注册
#define RegisterProduct(AbstractProduct, ConcreteProduct) \
	static ConcreteProductTool<AbstractProduct, ConcreteProduct> register##ConcreteProduct(#ConcreteProduct);

  • factory.cpp
#include "factory.h"
#include <iostream>

class Shoes
{
public:
	virtual void show() = 0;
};

class Nike :public Shoes
{
public:
	void show() override {
		std::cout << "nike shoes" << std::endl;
	}
};
//注册Nike到Shoes的工厂类中
RegisterProduct(Shoes, Nike)

class Adidas : public Shoes
{
public:
	void show() override{
		std::cout << "adidas shoes" << std::endl;
	}
};
//注册Adidas到Shoes的工厂类中
RegisterProduct(Shoes, Adidas)


class Clothe
{
public:
	virtual void display() = 0;
};

class Shirt :public Clothe
{
public:
	void display() override {
		std::cout << "Shit" << std::endl;
	}
};
//注册Shirt类到Clothe的工厂类中
RegisterProduct(Clothe, Shirt)

class Dress :public Clothe
{
public:
	void display() override {
		std::cout << "Dress" << std::endl;
	}
};
//注册Dress类到Clothe的工厂类中
RegisterProduct(Clothe, Dress)


void factorytest()
{
	Shoes *shoe1 = ProductFactory<Shoes>::instance().createProduct("Nike");
	Shoes *shoe2 = ProductFactory<Shoes>::instance().createProduct("Adidas");

	shoe1->show();
	shoe2->show();

	Clothe *clothe1 = ProductFactory<Clothe>::instance().createProduct("Shirt");
	Clothe *clothe2 = ProductFactory<Clothe>::instance().createProduct("Dress");
	clothe1->display();
	clothe2->display();

	delete shoe1;
	delete shoe2;
}
  • 自己定义好产品基类,写好对应的子类,调用注册宏就可以实现注册对应产品类到对应的工厂类,这也可以屏蔽对应子类的头文件,只要注册了,然后工厂单例知道对应的类名称就可以生产了,完全地解耦,很方便,这里只是提供了一个简单的样例,可以根据对应的业务场景去丰富。
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值