对象工厂 Object Factory又名简单工厂模式,貌似不属于设计模式范畴。它的作用是把对象的创建工作集中起来,并使创建工作与其它部分解耦。比如下面这个函数也可当作简单工厂: - CWinBase* Create(string s)
- {
- if(s == "Edit")
- return new CEdit;
- else if(s == "Button")
- return new CButton;
- ...
- }
Loki库的Factory类提供了对简单工厂模式的支持。 头文件类型- template<
- class AbstractProduct,
- typename IdentifierType,
- typename CreatorParmTList = NullType,
- template< typename, class > class FactoryErrorPolicy = DefaultFactoryError>
- class Loki::Factory;
成员方法bool Register(const IdentifierType& id, ProductCreator creator); | 以id作为识别码注册生成器。函数、对象方法或仿函数都可以作为生成器。 | bool Unregister(const IdentifierType& id); | 取消注册 | std::vector RegisteredIds(); | 取得已注册的所有识别码 | AbstractProduct* CreateObject(const IdentifierType& id); AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1); AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2); ... | 按识别码id生成对象(调用对应的生成器) |
示例代码- #include
- #include
- #include
- #include
-
- struct IWidget{
- virtual void printName() = 0;
- virtual ~IWidget(){;}
- };
- typedef Loki::Factory widget_factory_t;</iwidget, std::string>
- struct CButton : IWidget{
- void printName()
- {
- std::cout << "CButton" << std::endl;
- }
- };
- struct CEdit : IWidget{
- void printName()
- {
- std::cout << "CEdit" << std::endl;
- }
- };
- struct CListBox : IWidget{
- void printName()
- {
- std::cout << "CListBox" << std::endl;
- }
- };
-
- int _tmain(int argc, _TCHAR* argv[])
- {
-
- widget_factory_t wf;
-
- wf.Register("Edit", Loki::CreateUsingNew::Create );
- wf.Register("Button", Loki::CreateUsingNew::Create );
- wf.Register("ListBox", Loki::CreateUsingNew::Create );
-
- {
- IWidget* pWid = wf.CreateObject("Edit");
- pWid->printName();
- delete pWid;
- }
- {
- IWidget* pWid = wf.CreateObject("ListBox");
- pWid->printName();
- delete pWid;
- }
- return 0;
- }
很多时候,工厂往往只需要一个实例,我们可以使用前面说过的SingletonHolder把widget_factory_t弄成Singleton模式。 上面生成CButton之类的窗体时使用的是默认构造,所以我偷懒没写各个类的生成器,直接用了Loki::CreateUsingNew。 如果你的类有构造参数的话,那么就得在Loki::Factory模板参数中指出参数类型,并且自定义生成器,就象这样: - #include
- #include
- #include
-
- struct IWidget{
- virtual void printName() = 0;
- virtual ~IWidget(){;}
- };
- typedef Loki::Factory<
- IWidget,
- std::string,
- Loki::Seq<int, char>
- > widget_factory_t;
- typedef Loki::SingletonHolder<widget_factory_t, loki::createusingnew,< span=""></widget_factory_t, loki::createusingnew,<>
- Loki::LongevityLifetime::DieAsSmallObjectChild> Singleton_Fac;
- struct CButton : IWidget{
- void printName()
- {
- std::cout << "CButton:" << m_txt << std::endl;
- }
- CButton(std::string txt, int, char)
- :m_txt(txt){}
- std::string m_txt;
- };
- struct CEdit : IWidget{
- void printName()
- {
- std::cout << "CEdit:" << m_txt << std::endl;
- }
- CEdit(std::string txt, int, char)
- :m_txt(txt){}
- std::string m_txt;
- };
- struct CListBox : IWidget{
- void printName()
- {
- std::cout << "CListBox:" << m_txt << std::endl;
- }
- CListBox(std::string txt, int, char)
- :m_txt(txt){}
- std::string m_txt;
- };
- template<class T> struct CreateT
- {
- T * operator()(std::string txt, int p1, char p2) const
- {
- return new T(txt, p1, p2);
- }
- };
-
- int _tmain(int argc, _TCHAR* argv[])
- {
-
- widget_factory_t& wf = Singleton_Fac::Instance();
-
-
- wf.Register("Edit", CreateT() );
- wf.Register("Button", CreateT() );
- wf.Register("ListBox", CreateT() );
-
-
- {
- IWidget* pWid = wf.CreateObject("Edit", "Hello", 0, ‘ ‘);
- pWid->printName();
- delete pWid;
- }
- {
- IWidget* pWid = wf.CreateObject("ListBox", "World", 0, ‘ ‘);
- pWid->printName();
- delete pWid;
- }
-
- return 0;
- }
Loki::Seq是一个类似于TypeList的东东,可以存放一系列的类型。另外用SingletonHolder包装Factory时,一定要用Loki::LongevityLifetime::DieAsSmallObjectChild作为SingletonHolder的lifttime策略(Loki使用说明上说的,由于Factory使用了Loki内部的内存管理器SmallObject)。 |