C++实现注册机制的工厂模式

需求分析

对于项目ZcET,需要获取项目ZcBT和项目ZcTT中模型的mesh,但是ZcET、ZcBT、ZcTT互相不依赖和不包含,
但是这三个项目同时依赖于项目ZcUT,此时就需要ZcUT作为中间项目,传递ZcBT,ZcTT的模型mesh,类图如下

项目关系类图

实现方法

1、提供一个工厂对象
2、实现工厂的注册功能,这里使用宏注册,注册名用“key”表示
3、在ZcBT和ZcTT中提供接口实现,通过参数控制,传出所需mesh
4、注册这个接口函数
5、在ZcET中获取所需的mesh

注:对象通过注册保存在工厂的变量(map)中static std::map<QString, CreatorFunc> m_mMesh;以下是详细的实现方法

工厂对象 (ZcUT中创建)

	//.h
	/// @brief 网格接口类
	class ZCUTILITIES_EXPORT MeshInf
	{
	public:
		MeshInf();
		 ~MeshInf();

	public :
		/// @brief 创建mesh
		/// @param varlist 建模参数
		/// @param meshes mesh数组
		virtual void createMesh(const QVariantMap& varlist, std::vector<ZcApp::ProGeMesh>& meshes) = 0;
	};

	///  工厂类 (注册)
	class ZCUTILITIES_EXPORT MeshFactory
	{
	public:
		MeshFactory() {}
		virtual ~MeshFactory() {}

	public:
		using CreatorFunc = std::function<MeshInf* ()>;

		static void registerCreator(const QString& key, CreatorFunc func);

		static MeshInf* create(const QString& key);

	private:
		static std::map<QString, CreatorFunc> m_mMesh;
	};

	// 注册宏
#define REGISTER_MESH(KEY, CLASSNAME) \
    namespace { \
        const bool reg_##CLASSNAME = [](){ \
            ZcUtility::MeshFactory::registerCreator(KEY, [](){ return new CLASSNAME(); }); \
            return true; \
        }(); \
    }
//.h
MeshInf::MeshInf()
{
}

MeshInf::~MeshInf()
{
}


std::map<QString, MeshFactory::CreatorFunc> MeshFactory::m_mMesh;

void MeshFactory::registerCreator(const QString& key, CreatorFunc func)
{
	m_mMesh[key] = func;
}

MeshInf* MeshFactory::create(const QString& key)
{
	auto it = m_mMesh.find(key);
	if (it != m_mMesh.end())
		return it->second();
	return nullptr;
}

ZcTT中接口实现

	class GuardImpl : public ZcUtility::MeshInf
	{
	public:
		GuardImpl(){}
		~GuardImpl(){}

	public:
		virtual void createMesh(const QVariantMap& varlist, std::vector<ZcApp::ProGeMesh>& meshes) override;
	};

在.cpp中GuardImpl 实现之后再注册类

void GuardImpl::createMesh(const QVariantMap& varlist, std::vector<ZcApp::ProGeMesh>& meshes)
{;;;;}
	//自动注册
	REGISTER_MESH("Guard", GuardImpl);

ZcET获取ZcTT中的mesh

	std::unique_ptr<ZcUtility::MeshInf> guardInf(ZcUtility::MeshFactory::create("Guard"));
	std::vector<ProGeMesh> vGuardMeshs;
	if (guardInf)
	{
		guardInf->createMesh(varlist, vGuardMeshs);
	}

总结:工厂注册机制解决了不同项目数据传输的困难,避免了普通工厂互相包含、互相依赖的耦合、提高程序的可读性,降低耦合度,但是需要注意的是,注册宏在程序一开始运行时就会加载,如果整个软件是在某处统一注册类实体,可能会造成注册宏的dug困难。

更多推荐