在简单工厂模式中,在工厂类中,需要加入switch或者if判断,增加了代码的耦合性,不利于扩展。
引入反射机制则可以去除判断,而是根据传入的字符串直接生产对应的实例
未加入反射机制的简单工厂
class Fruit
{
public:
virtual void eat() = 0;
};
class apple:public Fruit
{
public:
void eat()
{
cout<<"吃苹果"<<endl;
}
};
class banana:public Fruit
{
public:
void eat()
{
cout<<"吃香蕉"<<endl;
}
};
class pear:public Fruit
{
public:
void eat()
{
cout<<"吃梨"<<endl;
}
};
class factory
{
public:
void createFruit(string name)//通过传入的字符串进行判断,生成对应的实例,扩展性较差
{
if(name=="苹果")
{
fruit = new apple;
}
if(name=="香蕉")
{
fruit = new banana;
}
if(name=="梨")
{
fruit = new pear;
}
return fruit;
}
private:
Fruit *fruit;
};
加入反射机制的简单工厂
Factory.h
可以将其进行封装,方面使用
#ifndef _FACTORY_H
#define _FACTORY_H
#include<iostream>
using namespace std;
#include<map>
#include<string>
typedef void* (*create_fun)();
#define REGISTER(className) \
className* objectCreator##className(){ \
return new className; \
} \
RegisterAction g_creatorRegister##className( \
#className,(create_fun)objectCreator##className)
class Factory
{
public:
~Factory(){}
void *GetClassByName(string name)
{
std::map<string,create_fun>::iterator ite = my_class.find(name);
if(ite==my_class.end())
return NULL;
else
return ite->second();
}
void RegisterClass(string name,create_fun fun)
{
my_class[name]=fun;
}
static Factory& GetInstance()
{
static Factory f;
return f;
}
private:
Factory(){}
std::map<string,create_fun> my_class;
};
#endif
test.h
class Fruit
{
public:
virtual void eat() = 0;
};
class apple:public Fruit
{
public:
void eat()
{
cout<<"吃苹果"<<endl;
}
};
class banana:public Fruit
{
public:
void eat()
{
cout<<"吃香蕉"<<endl;
}
};
class pear:public Fruit
{
public:
void eat()
{
cout<<"吃梨"<<endl;
}
};
class factory
{
public:
void createFruit(string name)//不需要判断语句,直接根据字符创生产对应实例,方便扩展
{
this->fruit = (Fruit*)Factory::GetInstance().GetClassByName(name);
}
public:
Fruit *fruit;
};
class RegisterAction{
public:
RegisterAction(string className,create_fun ptrCreateFn){
Factory::GetInstance().RegisterClass(className,ptrCreateFn);
}
};
main.h
#include"Factory.h"
#include"test.h"
REGISTER(apple);//注册apple类
int main()
{
factory *t = new factory;
t->createFruit("apple");
t->fruit->eat();
delete t;
system("pause");
return 0;
}
扩展
如果此时有一个新的水果加入,则只需要继承Fruit即可,不需要修改代码