C++设计模式探讨(1)-工厂模式

发布于:2024-04-20 ⋅ 阅读:(27) ⋅ 点赞:(0)

设计模式是架构设计之术,但不是道。是技巧和方法论,但不是核心思想。设计模式是世界规律的提取,但无法体现具体的形式。所以,设计模式是一个尴尬的存在,它有一定的价值,但却又十分有限。架构设计者需要做的是,知道有这么个规律,基于此去深思和挖掘内涵,这一切基于设计之道。

这里探讨下工厂模式。援引其他地方的介绍为:C++工厂模式是一种模式,它是一种创建对象的有效方法。它允许我们使用一个类来负责创建实现特定接口的不同具体类的实例,而无需明确指定该实例的具体类。通过抽象出一个工厂类来负责每个子类的实例化,使得代码的可维护性大大增加。这种模式也使得添加新类型的实例变得容易,只要扩展工厂类即可。

可以看到工厂模式的实现特点是:1.有一个父类作为统一的对外封装和类型描述;2.子类通过父类统一的接口来创建,实例对外体现为父类类型;3.子类实例内的成员可以基于父类拓展,在调用的时候通过子类实例直接调用。

具体实现方式可以通过std::map来实现比较方便。不要简单的用if else,或者switch case, 他们不能很好去耦合。 通过map实现的工厂模式比较简单的示例:

#include "executormanager.h"
#include "executor.h"
#include "executordigtron.h"
#include "executorled.h"
#include "executorrelay.h"
#include "executor_playsound.h"

ExecutorManager::ExecutorManager()
{
	ExecutorDigtron *pDigitron = new ExecutorDigtron();
	ExecutorLed * led = new ExecutorLed();
	ExecutorRelay * relay = new ExecutorRelay();
	ExecutorPlaysound *playsound = new ExecutorPlaysound();

	Insert("DIGITRON", (Executor*)pDigitron);
	Insert("LED", (Executor*)led);
	Insert("RELAY", (Executor*)relay);
	Insert("SOUND", (Executor*)playsound);
}

ExecutorManager::~ExecutorManager()
{
	cout <<  __FUNCTION__ <<endl;

	for (auto iter=mExecutorMap.begin();iter!=mExecutorMap.end();iter++)
        {
                delete iter->second;
        }
	
}

void ExecutorManager::Insert(const string& type, Executor* executor)
{
	pair<ExecutorMap::iterator, bool> ret;
	
	ret = mExecutorMap.insert(pair<string, Executor*>(type, executor));
	
	if(ret.second == false)
	{
		cout<<"insert failed:" <<type;
	}		 
}


void ExecutorManager::execute(string type, string value, string method, string target)
{
	ExecutorMap::iterator it = mExecutorMap.find(type);
    if(it != mExecutorMap.end())
		mExecutorMap[type]->execute(value, method, target);
	else
		printf("type %s is not in executorMap\n", type.c_str());
}
int ExecutorManager::getState(string type)
{
	return mStateMap[type];
}
void ExecutorManager::setState(string type, int state)
{
	mStateMap[type] = state;
}

这种方式相对简单,如果要实现更便捷的子类实例入map方式,可以使用静态反射机制。在下一贴我再介绍下这个方法。