日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

工厂对象模式简介

發布時間:2025/3/20 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 工厂对象模式简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在GoF的《設計模式》一書中,對Factory Method/Object Method 意圖描述如下:

定義一個用于創建對象的接口,讓子類決定實例化是哪一個類。 Factory Metho是一個類的實例化延遲到其子類。

其結構圖如下:

其中, 類 Product 定義了一類對象的接口。 ConcreteProduct 實現 Product 的接口。 Creator是工廠方法的包裝器。ConcreteCreator 類實現Creator的接口。基于以上結構,每個ConcreteProduct必須帶有一個 ConcreteCreator, 用來產生特定的ConcreteProduct。

這種實現的缺點,在《設計模式》一書中也提到過一點 是客戶可能僅僅想創建一個特定的 ConcreteProduct 對象,但必須額外創建 Creator 的子類。 在ConcreteProduct 的演化上造成額外的工作量。 另一點從代碼簡潔之道角度來看,每一個 ConcreteCreator 的實現都幾乎一樣,就像一幕幕乏味的樣板戲,簡直就是雞肋。

那么如何改進呢?

?

用boost factory & boost function實現對象工廠

?

文件:ObjectFactory.h

?

??

[cpp]?view plain?copy
  • #ifndef?MP_OBJECT_FACTORY_H??
  • #define?MP_OBJECT_FACTORY_H??
  • #include?<boost/function.hpp>??
  • #include?<map>??
  • ??
  • ///?工廠模式泛型實現.??
  • ///?限制:?生成的對象必須為通過默認構造函數來構造.??
  • ///?當然你也可以擴展這個模板讓它支持更多參數的構造函數.??
  • template<typename?IdType,?typename?ObjectType>??
  • class?ObjectFactory??
  • {??
  • public:??
  • ????///?表示默認構造函數的函數對象.??
  • ????typedef?boost::function<?ObjectType*?()?>?CreatorType;??
  • ??
  • ????///?構造函數對應的函數對象的關聯容器.???
  • ????typedef?std::map<IdType,?CreatorType>?ObjectCreator_map;??
  • ??
  • ????///?注冊子類對象的構造函數信息.??
  • ????void?RegisterObjectCreator(const?IdType&?id,?const?CreatorType?&creator)??
  • ????{??
  • ????????objectCreatorMap_[id]?=?creator;??
  • ????}??
  • ??
  • ????///?通過默認構造函數在堆上創建一個新的對象實例.?使用new生成.??
  • ????ObjectType?*?MakeObject(const?IdType&?id)??
  • ????{??
  • ????????ObjectCreator_map::const_iterator?iter?=?objectCreatorMap_.find(id);??
  • ????????if?(iter?==?objectCreatorMap_.end())??
  • ????????{??
  • ????????????return?NULL;??
  • ????????}??
  • ????????else??
  • ????????{??
  • ????????????return?(iter->second)();??
  • ????????}??
  • ????}??
  • ??
  • private:??
  • ????ObjectCreator_map?objectCreatorMap_;??
  • };??
  • ??
  • #endif??
  • ?

    以上代碼中,模板ObjectFactor接收兩個參數,第一個參數IdType是用來標識是哪種子類對象的關鍵字。ObjectType是基類對 象類型。也就是上面結構圖中的Product。為了實現創建ConcreteProduct對象的方法,我們需要獲得每個子類對象的構造函數信息,通過 RegisterObjectCreator方法我們將子類對象的構造函數信息保存在工廠中。? 那么哪種數據結構表示構造函數信息呢? 通過普通函數指針,好像行不通。在這里我們用到了 boost::function,它可以將任意的函數信息封裝到function object對象中,從而可以實現賦值,調用等操作。

    以上工廠實現中我們將任意類型的默認構造函數信息用 boost::function 進行封裝,表示成 typedef boost::function< ObjectType* () > CreatorType;

    后面我們就是建一張表來關聯IdType與它所對應ConcreteProduct的構造函數信息。這里我們直接用 std::map關聯容器來存儲。

    RegisterObjectCreator用于注冊ConcreteProduct對象的構造函數信息。

    MakeObject用于根據傳入的IdType來生成對應的ConcreteProduct對象。注意這一句 (iter->second)(); 它返回指向ObjectType對象的指針。? 實際上iter->second返回是一個CreatorType 類型函數對象,對一個函數對象進行()調用。因為CreatorType是對構造函數的封裝,因此實際上是調用ConcreteProduct的構造函數 生成一個ConcreteProduct對象。 后面會看到 CreatorType 是我們用 boost::factory 封裝的,它默認會調用new操作符從堆上構造一個ConcreteProduct對象。

    ?

    ?

    如何使用對象工廠

    ?

    我們來實現GoF Factory Method結構圖中類似的代碼。

    首先我們定義幾個類:

    Product????????????????? --? 產品類接口封裝,定義了類對象的接口。

    ConcreteProductA? --? 具體的產品A,該類 實現 Product 的接口。

    ConcreteProductB? --? 具體的產品B,該類 實現 Product 的接口。

    文件:Product.h

    ?

    ?

    [cpp]?view plain?copy
  • #ifndef?MP_PRODUCT_H??
  • #define?MP_PRODUCT_H??
  • #include?<boost/shared_ptr.hpp>??
  • ??
  • class?Product??
  • {??
  • public:??
  • ????explicit?Product()?{};??
  • ????virtual?~Product()?{};??
  • ????virtual?void?DoSomething()?=?0;??
  • };??
  • ??
  • typedef?boost::shared_ptr<Product>?Product_ptr;??
  • ??
  • #endif??
  • ?

    文件:ConcreteProductA.h

    ?

    [cpp]?view plain?copy
  • #ifndef?MP_CONCRETE_PRODUCT_A_H??
  • #define?MP_CONCRETE_PRODUCT_A_H??
  • #include?<iostream>??
  • ??
  • class?ConcreteProductA??
  • ????:public?Product??
  • {??
  • public:??
  • ????void?DoSomething()??
  • ????{??
  • ????????std::cout<<__FUNCTION__<<std::endl;??
  • ????}??
  • };??
  • ??
  • ??
  • #endif??
  • ?

    ?

    文件:ConcreteProductB.h

    ?

    [cpp]?view plain?copy
  • #ifndef?MP_CONCRETE_PRODUCT_B_H??
  • #define?MP_CONCRETE_PRODUCT_B_H??
  • #include?<iostream>??
  • ??
  • class?ConcreteProductB??
  • ????:public?Product??
  • {??
  • public:??
  • ????void?DoSomething()??
  • ????{??
  • ????????std::cout<<__FUNCTION__<<std::endl;??
  • ????}??
  • };??
  • ??
  • ??
  • #endif??
  • ?

    ?

    下面我們來測試上面的對象工廠。

    文件: Main.cpp

    ?

    [cpp]?view plain?copy
  • #include?"Product.h"??
  • #include?"ConcreteProductA.h"??
  • #include?"ConcreteProductB.h"??
  • #include?"ObjectFactory.h"??
  • #include?<string>??
  • #include?<boost/functional/factory.hpp>??
  • ??
  • ??
  • int?main(int?argc,?char?**argv)??
  • {??
  • ????ObjectFactory<std::string,?Product>?productFactory;?//?對象工廠??
  • ?????
  • ????//?注冊對象構造器.??
  • ????productFactory.RegisterObjectCreator("PRODUCT_A",?boost::factory<ConcreteProductA?*>()?);??
  • ????productFactory.RegisterObjectCreator("PRODUCT_B",?boost::factory<ConcreteProductB?*>()?);??
  • ??
  • ????//通過工廠生成對象,?存儲在shared_ptr中.??
  • ????Product_ptr?productA(?productFactory.MakeObject("PRODUCT_A")?);??
  • ????Product_ptr?productB(?productFactory.MakeObject("PRODUCT_B")?);??
  • ??
  • ????//?演示多態性質。??
  • ????productA->DoSomething();??
  • ????productB->DoSomething();??
  • ????return?0;??
  • }??
  • ??

    ?

    在以上測試中,我們首先生成一個對象工廠,這里我們以std::string作為IdType來標示是哪種類型的ConcreteProduct。

    然后向工廠中注冊具體類的構造方法: productFactory.RegisterObjectCreator("PRODUCT_A", boost::factory<ConcreteProductA *>() ); 注意:這里用到了boost::factory,它可以將 new 表達式封裝成函數對象(function object),? 這也正式我們工廠的注冊方法所需要的參數。

    后面我們調用對象工廠的MakeObject來生成我們期望的ConcreteProduct對象。 我們用一個字符串來標識要生成哪種類型的ConcreteProduct對象。同時我們將返回的對象指針保存在 shared_ptr中,從而實現對象的自動管理。 類型Product_ptr的定義為: typedef boost::shared_ptr<Product> Product_ptr;? 它是對Product接口的智能指針封裝。

    最后,就是展示多態行為的時候了,我們調用不同ConcreteProduct對象的DoSomething來演示。運行效果如下:

    ?

    ?

    限制說明:

    1. 本文只是實現了帶有默認構造函數的對象工廠。 如果你愿意也可以實現帶有多個參數構造函數的對象工廠。

    2. ObjectFactory 也可以實現為Singleton模式,根據個人需要吧,本文的重點不在這里。



    本文轉自莫水千流博客園博客,原文鏈接:http://www.cnblogs.com/zhoug2020/p/5912281.html,如需轉載請自行聯系原作者

    總結

    以上是生活随笔為你收集整理的工厂对象模式简介的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。