创建型模式-----工厂模式

目录

基本概念

使用场景

模式定义:

工厂方法UML图

工厂方法代码

项目中简单工厂的使用

背景

简单工厂模式应用代码


基本概念

使用场景

        在软件系统总行经常面临对象的创建工作,但是由于需求的变化或设备的迭代导致需要创建的对象经常变化;工厂模式是一种常见的创建型方法,提供一定的封装机制从而避免程序主体框架与具体的对象创建工作产生紧耦合,从而增加程序的扩展性。

模式定义:

        工厂模式主要是定义一个创建对象的接口,通过虚函数让子类决定实例化具体的对象,使得类的实例化延迟到子类中,从而达到解耦的目的。

工厂方法UML图

工厂方法代码

LED部分代码:

//产品LED抽象类 
class AbstractLed
{
public:
	AbstractLed() {};
	virtual ~AbstractLed() {};
	virtual void showText(const string&msg) = 0;
	virtual void playVoice(const string&msg) = 0;
};

//具体的LED
class OnBangLed :public AbstractLed
{
public:
	OnBangLed() {};
	~OnBangLed() {};
	void showText(const string&msg) override {
		/*
		...
		*/
	}
	void playVoice(const string&msg)override {
		/*
		...
		*/
	}
};

class JIaKeLed :public AbstractLed
{
public:
	JIaKeLed() {};
	~JIaKeLed() {};
	void showText(const string&msg) override {
		/*
		...
		*/
	}
	void playVoice(const string&msg)override {
		/*
		...
		*/
	}
};

class LingXinLed :public AbstractLed
{
public:
	LingXinLed() {};
	~LingXinLed() {};
	void showText(const string&msg) override {
		/*
		...
		*/
	}
	void playVoice(const string&msg)override {
		/*
		...
		*/
	}
};

工厂部分代码:

//这里抽象出工厂 不同产品工厂继承此抽象工厂
//若有新的产品继承新建产品工厂即可 区别于简单工厂打破工厂封装
class AbstractFactory
{
public:
	AbstractFactory() {}
	~AbstractFactory() {};

	virtual AbstractLed*CreateLed() = 0;
};

class OnBangLedFactory:public AbstractFactory
{
public:
	OnBangLedFactory() {}
	~OnBangLedFactory() {};

	AbstractLed*CreateLed() {
		return new OnBangLed();
	};
};

class JIaKeLedFactory :public AbstractFactory
{
public:
	JIaKeLedFactory() {}
	~JIaKeLedFactory() {};

	AbstractLed*CreateLed() {
		return new JIaKeLed();
	};
};


//具体的工厂对象也可以结合单例构造,这里灵信屏举例
#define g_LingXinLedHelper  Singleton<LingXinLedFactory>::getInstance()

class LingXinLedFactory :public AbstractFactory
{
	friend Singleton<LingXinLedFactory>;
public:
	LingXinLedFactory() {}
	~LingXinLedFactory() {};

	AbstractLed*CreateLed() {
		return new LingXinLed();
	};
};

测试部分:

void TestLed()
{
	vector<AbstractLed*>ledVec;
	ledVec.push_back(JIaKeLedFactory().CreateLed());
	ledVec.push_back(OnBangLedFactory().CreateLed());
	ledVec.push_back(g_LingXinLedHelper->CreateLed());
	string msg("测试");
	for (auto iter : ledVec)
	{
		iter->playVoice(msg);
		iter->showText(msg);
	}
}

项目中简单工厂的使用

背景

        实际项目中,软件添加的外设越来越多,且许多设备逐渐朝集成化方向发展,新老设备功能有交集,各有特色,同时考虑老设备的兼容问题以及未来新设备的扩展,工厂模式在设备管理中重构中有一定的优势。下面以简单工厂模式进行举例说明。

简单工厂模式应用代码

 设备抽象:这里设备接口定义所有设备功能的合集,采用hasFeature在子设备中做功能区分,以及相应功能实现。

enum class DeviceFeature :char
{
	BarrierCtrl,         //道闸能力
	ShowText,                 
	PlayVoice,          
	DisPlayQrCode,       //二维码
	CapturePlate,       //车牌
	CaptureFace        //人脸
};

enum class DeviceType :char
{
	FaceCamera,
	PlateCamera,
	NetGuard,
	LED_OnBang,
	LED_JiaKe
	/*
	...
	*/
};

struct DeviceParam
{
	string ip;
	int port;
	string com;
	string DevSerialNo;
	string url;
	/*
	所有设备参数的合集
	...
	*/
};

class AbstractDevice
{
public:
	AbstractDevice() {};
	virtual ~AbstractDevice() {};
	//设备类型越来越多 功能交织 此处hasFeature做区分
	void setParam(const DeviceParam&param) { m_param = param; };
	virtual bool hasFeature(DeviceFeature feature) = 0;
	virtual void showText(const string&msg) {};
	virtual void playVoice(const string&msg) {};
	virtual void captureFace() {};
	virtual void capturePlate() {};
	virtual void openBarrier() {};
	/*
	所有设备能力合集的函数
	各个设备根据自身能力重载
	*/
private:
	DeviceParam m_param;
};

子设备继承实现:据子设备功能重载hasfeature函数,和设备具有的功能函数。

class JiaKeLedDev:public AbstractDevice
{
public:
	JiaKeLedDev() {};
	bool hasFeature(DeviceFeature feature) override
	{
		switch (feature)
		{
		case DeviceFeature::ShowText:
		case DeviceFeature::PlayVoice:
			return true;
		default:
			return false;
		}
	}
	void showText(const string&msg) override 
	{
		std::cout << "佳科LED显示测试:" << msg << endl;
	};
	void playVoice(const string&msg) override 
	{
		std::cout << "佳科LED播放测试:" << msg << endl;
	};
};

class OnBongDev :public AbstractDevice
{
public:
	OnBongDev() {};
	bool hasFeature(DeviceFeature feature) override
	{
		switch (feature)
		{
		case DeviceFeature::ShowText:
		case DeviceFeature::PlayVoice:
			return true;
		default:
			return false;
		}
	}
	void showText(const string&msg) override
	{
		std::cout << "仰邦LED显示测试:" << msg << endl;
	};
	void playVoice(const string&msg) override
	{
		std::cout << "仰邦LED播放测试:" << msg << endl;
	};
};

class PlateCameraDev :public AbstractDevice
{
public:
	PlateCameraDev() {};
	bool hasFeature(DeviceFeature feature) override
	{
		switch (feature)
		{
		case DeviceFeature::CapturePlate:
		case DeviceFeature::PlayVoice:
			return true;
		default:
			return false;
		}
	}
	void capturePlate() override
	{
		std::cout << "车牌抓拍机抓拍车牌测试" << endl;
	};
	void playVoice(const string&msg) override
	{
		std::cout << "车牌抓拍机播放测试:" << msg << endl;
	};
};

class FaceCameraDev :public AbstractDevice
{
public:
	FaceCameraDev() {};
	bool hasFeature(DeviceFeature feature) override
	{
		switch (feature)
		{
		case DeviceFeature::CaptureFace:
		case DeviceFeature::PlayVoice:
			return true;
		default:
			return false;
		}
	}
	void captureFace() override
	{
		std::cout << "人脸抓拍机抓拍车牌测试" << endl;
	};
	void playVoice(const string&msg) override
	{
		std::cout << "人脸抓拍机播放测试:" << msg << endl;
	};
};

//道闸一体机 抓拍播报显示等能力集均有
class NetGuardDev :public AbstractDevice
{
public:
	NetGuardDev() {};
	bool hasFeature(DeviceFeature feature) override
	{
		switch (feature)
		{
		case DeviceFeature::CaptureFace:
		case DeviceFeature::CapturePlate:
		case DeviceFeature::PlayVoice:
		case DeviceFeature::ShowText:
		case DeviceFeature::BarrierCtrl:
			return true;
		default:
			return false;
		}
	}
	void capturePlate() override
	{
		std::cout << "道闸一体机抓拍车牌测试" << endl;
	};
	void captureFace() override
	{
		std::cout << "道闸一体机抓拍车牌测试" << endl;
	};
	void playVoice(const string&msg) override
	{
		std::cout << "道闸一体机播放测试:" << msg << endl;
	};
	void showText(const string&msg) override
	{
		std::cout << "道闸一体机显示测试:" << msg << endl;
	};
	void openBarrier() override
	{
		std::cout << "道闸一体机开闸测试:" << endl;
	};
};

设备工厂代码:这里复用单例便于全局使用,使用std::function存储创建设备的函数。

//这里使用单例模板 便于设备工厂全局使用
#define g_DeviceHelper Singleton<DeviceFactory>::getInstance()
class DeviceFactory
{
	friend Singleton<DeviceFactory>;
public:
	void registerDevice(DeviceType deviceType, std::function<AbstractDevice*()>creator)
	{
		creatorMap[deviceType] =  creator;
	}
	AbstractDevice*createLed(DeviceType deviceType,const DeviceParam&param)
	{
		auto iter = creatorMap.find(deviceType);
		if (iter != creatorMap.end())
		{
			//实际项目中这里用unique_ptr<AbstractDevice>便于内存管理
			AbstractDevice*pDev = iter->second();
			pDev->setParam(param);
			return pDev;
		}
		return nullptr;	
	}
private:
	DeviceFactory() {};
	unordered_map<DeviceType, function<AbstractDevice*()>>creatorMap;
};

设备创建函数等级:在使用工厂前,需要登记设备的创建函数(registerDevice),这里将实际的登记单独从设备工厂里面抽出来,后续若新增设备只需继承AbstractDevice独立开发,在软件初始登记模块增加一行登记即可,保证DeviceFactory类封闭性便于扩展。

void TestFun::TestFactory()
{
	//注册创建函数 一般在软件启动时注册一次
	g_DeviceHelper->registerDevice(DeviceType::LED_JiaKe, [](){ return new JiaKeLedDev(); });
	g_DeviceHelper->registerDevice(DeviceType::LED_OnBang, [](){ return new OnBongDev(); });
	g_DeviceHelper->registerDevice(DeviceType::FaceCamera, [](){ return new FaceCameraDev(); });
	g_DeviceHelper->registerDevice(DeviceType::PlateCamera, [](){ return new PlateCameraDev(); });
	g_DeviceHelper->registerDevice(DeviceType::NetGuard, [](){ return new NetGuardDev(); });
	
	vector<AbstractDevice*>ledVec;
	DeviceParam param1, param2, param3, param4, param5;
	//参数配置...

	ledVec.push_back(g_DeviceHelper->createLed(DeviceType::LED_JiaKe,param1));
	ledVec.push_back(g_DeviceHelper->createLed(DeviceType::LED_OnBang, param2));
	ledVec.push_back(g_DeviceHelper->createLed(DeviceType::FaceCamera, param3));
	ledVec.push_back(g_DeviceHelper->createLed(DeviceType::PlateCamera, param4));
	ledVec.push_back(g_DeviceHelper->createLed(DeviceType::NetGuard, param5));

	string msg("测试");
	for (auto iter : ledVec)
	{
		if (iter->hasFeature(DeviceFeature::ShowText))
		{
			iter->showText(msg);
		}
		if (iter->hasFeature(DeviceFeature::PlayVoice))
		{
			iter->playVoice(msg);
		}
		if (iter->hasFeature(DeviceFeature::CaptureFace))
		{
			iter->captureFace();
		}
		if (iter->hasFeature(DeviceFeature::CapturePlate))
		{
			iter->capturePlate();
		}
		if (iter->hasFeature(DeviceFeature::BarrierCtrl))
		{
			iter->openBarrier();
		}
	}
	
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值