动态配置工厂类

 这里的动态配置工厂,是指添加一个产品类时,不必去修改工厂类的代码,即可使工厂具备创建产品的能力。
为了描述简便,代码采用教科书中方式而非实际的代码。
 
我们有以下一组类:
 
//vehicle.h
class Vehicle
{
public :
    Vehicle(){}
    virtual ~Vehicle(){}
    virtual void Start() = 0;
};
 
//car.h
class Car : public Vehicle
{
public :
    Car(){}
    virtual ~Car(){}
    virtual void Start();
};
 
//car.cpp
void Car::Start()
{
    cout << "Car::Start" << endl;
}
 
 
//plane.h
class Plane : public Vehicle
{
public :
    Plane(){}
    virtual ~Plane(){}
    virtual void Start();
};
 
//plane.cpp
void Plane::Start()
{
    cout << "Plane::Start" << endl;
}
 
 
通常,我们会使用最简单的工厂方式来创建具体对象,如果对象需要序列化到文件,我们一般会采用字符串作为标记来创建对象。
 
//verhiclefactory.h
class VehicleFactory
{
public :
    VehicleFactory();
    ~VehicleFactory();
 
    Vehicle* Create(const char *name)
    {
        Assert(name);
       if (0 == stricmp(name,"car")) {
           return new Car();
       }
       else if (0 == stricmp(name,"plane")) {
           return new Plane();
       }
       return NULL;
    }
};
 
//main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
    VehicleFactory factory;
    Vehicle * car = factory.Create("car");
    if (car) {
       car->Start();
    }
    system("pause");
    return 0;
}
 
以上方式在大多数的情况下工作良好。当我们要添加一个具体交通工具类时,记得去修改VehicleFactory,添加一行代码即可。
但若我们要添加的产品类不在VehicleFactory所在的库或者说我们根本无法修改VehicleFactory的代码时。这中方式就很难奏效了。
 
下面是一种改进的方法,即在添加具体类时把创建逻辑注册给VehicleFactory。
 
//vehicle.h
class Vehicle
{
public :
    Vehicle(){}
    virtual ~Vehicle(){}
    virtual void Start() = 0;
    virtual const char* GetClassTag() const = 0;
};
 
typedef Vehicle* (*Create_Vehicle)();
 
#define DECLARE_FACTORY() /
   virtual const char* GetClassTag() const;/
   static Vehicle* CreateObject();
 
#define IMPLEMENT_FACTORY(class_name,class_tag) /
   const char* class_name::GetClassTag() const /
   {/
      return class_tag;/
   }/
   Vehicle* class_name::CreateObject() /
   {/
      return new class_name();/
   }/
   CreateEntryRegistry::AddCreateEntry add##class_name##create_entry(class_tag,class_name::CreateObject);
 
上面两个宏定义一个CreateObject的静态函数,用来创建具体的产品对象,程序在运行的时候把这个函数注册给CreateEntryRegistry。
注意最后一行:它定义一个CreateEntryRegistry::AddCreateEntry 的全局对象,它的唯一作用是,在main函数运行之前,调用CreateEntryRegistry::AddCreateEntry的构造函数,自动把CreateObject注册到CreateEntryRegistry中。
 
class CreateEntryRegistry
{
public :
   static CreateEntryRegistry* Instance();
 
   bool Register(const char *name,Create_Vehicle create_entry);
   Vehicle* Create(const char *name);
 
   struct AddCreateEntry
   {
      AddCreateEntry(const char *name,Create_Vehicle create_entry)
      {
         CreateEntryRegistry::Instance()->Register(name,create_entry);
      }
   };
 
   struct CompStringNoCase : public std::binary_function<string,string,bool>
   {
      bool operator()(const string &left,const string &right) const
      {
         return ::stricmp(left.c_str(),right.c_str()) < 0;
      }
   };
 
private :
   CreateEntryRegistry(){}
   ~CreateEntryRegistry(){}
   CreateEntryRegistry(const CreateEntryRegistry&);
   CreateEntryRegistry& operator = (const CreateEntryRegistry&);
private :
   typedef map<string,Create_Vehicle,CompStringNoCase> CreateEntryMap;
   CreateEntryMap m_createEntries;
};
 
CreateEntryRegistry* CreateEntryRegistry::Instance()
{
   static CreateEntryRegistry instance;
   return &instance;
}
 
bool CreateEntryRegistry::Register(const char *name,Create_Vehicle create_entry)
{
   assert(name);
   assert(create_entry);
 
   std::pair<CreateEntryMap::iterator,bool> ret =
      m_createEntries.insert(std::make_pair(string(name),create_entry));
 
   return ret.second;
}
 
Vehicle* CreateEntryRegistry::Create(const char *name)
{
   if (NULL == name) return NULL;
 
   CreateEntryMap::iterator p = m_createEntries.find(string(name));
 
   if (p != m_createEntries.end() && p->second)
   {
      return (*p->second)();
   }
 
   return NULL;
}
 
CreateEntryRegistry 是一个Singleton,它管理注册进来的创建函数。用来协助创建对象。有了它,VehicleFactory 变为:
 
//vehiclefactory.h
class VehicleFactory
{
public :
    VehicleFactory();
    ~VehicleFactory();
 
    Vehicle* Create(const char *name)
    {
       return CreateEntryRegistry::Instance()->Create(name);
    }
};
 
具体类只需在自己的定义文件和实现文件分别添加 DECLARE_FACTORY IMPLEMENT_FACTORY 两个宏就可以使VehicleFactory具有创建它们的能力。
 
//car.h
class Car : public Vehicle
{
public :
    Car(){}
    virtual ~Car(){}
    virtual void Start();
    DECLARE_FACTORY()
};
 
//car.cpp
IMPLEMENT_FACTORY(Car,"Car")
void Car::Start()
{
    cout << "Car::Start" << endl;
}
 
//plane.h
class Plane : public Vehicle
{
public :
    Plane(){}
    virtual ~Plane(){}
    virtual void Start();
    DECLARE_FACTORY()
};
 
//plane.cpp
IMPLEMENT_FACTORY(Plane,"plane")
void Plane::Start()
{
    cout << "Plane::Start" << endl;
}
 
在一些知名的框架中就是采用类似的思路实现对象创建功能的。在实际的软件代码中采用这种方式,能大大提高软件的灵活性,复用性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值