工厂模式将创建对象的代码从客户代码中分离,提供了一种在大系统中管理创建众多对象的有效方法。当从配置文件或流中创建对象时,经常采用这种模式。
这里提供一种通用实现,可以作为参考。
#include <map>
#include <boost/function.hpp>
namespace factory
{
template<class T, class Allocator=std::allocator<T> >
class simple_factory
{
public:
> template<typename Key>
T* operator()(Key&)
{
T* pT=static_cast<T*>(m_allocate.allocate(1));
m_allocate.construct(pT, T());
return pT;
}
private:
Allocator m_allocate;
};
template<typename Key, class T, class Allocator=std::allocator<T> >
class factory
{
public:
typedef Allocator allocator_type;
typedef typename Allocator::value_type value_type;
typedef typename Allocator::pointer pointer;
typedef typename Allocator::reference reference;
typedef Key key_type;
template<class Factory>
void insert(const key_type& key, Factory& factory)
{
m_factories.insert(std::make_pair(key, factory));
}
template<class Derive>
void insert_class(const key_type& key)
{
insert(key, simple_factory<Derive, allocator_type>());
}
pointer construct(const key_type& key) const
{
factories_type::const_iterator it=m_factories.find(key);
if(it!=m_factories.end())
return (it->second)(key);
return NULL;
}
void destroy(pointer p)
{
allocator_type a;
a.destroy(p);
a.deallocate(p, 1);
}
private:
typedef boost::function<pointer (key_type)> factory_type;
typedef std::map<key_type, factory_type, std::less<key_type>, typename allocator_type::rebind<std::pair<const typename key_type, typename factory_type> >::other > factories_type;
factories_type m_factories;
};
}
为了保证创建和销毁对象的一致性,工厂类提供了销毁对象的方法。
以下是个测试例子:
struct Base
{
int x;
};
struct A : public Base
{
A() { x=1; }
};
struct B : public Base
{
B() { x=2; }
};
void test()
{
factory::factory<int, Base> fact;
fact.insert_class<A>(1);
fact.insert_class<B>(2);
Base* pBase=fact.construct(1);
cout<<pBase->x<<endl;
fact.destroy(pBase);
}