{"id":274,"date":"2021-06-09T10:08:33","date_gmt":"2021-06-09T02:08:33","guid":{"rendered":"https:\/\/swordofmorning.com\/?p=274"},"modified":"2025-10-09T13:56:05","modified_gmt":"2025-10-09T05:56:05","slug":"design-pattern-02-factory-method-pattern","status":"publish","type":"post","link":"https:\/\/swordofmorning.com\/index.php\/2021\/06\/09\/design-pattern-02-factory-method-pattern\/","title":{"rendered":"\u8bbe\u8ba1\u6a21\u5f0f 02 \u5de5\u5382\u65b9\u6cd5\u6a21\u5f0f"},"content":{"rendered":"<p><div class=\"has-toc have-toc\"><\/div><\/p>\n<h2>\u4e00\u3001\u610f\u56fe<\/h2>\n<p>&emsp;&emsp;\u5b9a\u4e49\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u5bf9\u8c61\u7684\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u51b3\u5b9a\u5b9e\u4f8b\u5316\u54ea\u4e00\u4e2a\u5bf9\u8c61\u3002\u8bf4\u4eba\u8bdd\u5c31\u662f\uff1a\u5c06\u521b\u5efa\u5bf9\u8c61\u7684\u5de5\u4f5c\u4ea4\u7ed9\u4e00\u4e2a\u201c\u5de5\u5382\u201d\u6765\u5b8c\u6210\u3002<\/p>\n<h2>\u4e8c\u3001UML\u56fe<\/h2>\n<p><figure style=\"width: 571px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/cdn.swordofmorning.com\/SwordofMorning\/Article%20Images\/Design%20Pattern\/02\/Factory-Method_1.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  width=\"571\" height=\"194\" alt=\"\u56fe1\" class=\"size-full\" \/><figcaption class=\"wp-caption-text\">\u56fe1\uff1a\u5de5\u5382\u65b9\u6cd5\u6a21\u5f0fUML<\/figcaption><\/figure><br \/ >\n<noscript><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/cdn.swordofmorning.com\/SwordofMorning\/Article%20Images\/Design%20Pattern\/02\/Factory-Method_1.png\" width=\"571\" height=\"194\" alt=\"\u56fe1\" class=\"size-full\" \/> \u56fe1\uff1a\u5de5\u5382\u65b9\u6cd5\u6a21\u5f0fUML[\/caption]<br \/><\/noscript>\n&emsp;&emsp;\u6211\u4eec\u5728\u62bd\u8c61Creator\u4e2d\u7684\u7684FactoryMethod\u5982\u4e0b\uff0c\u8fd9\u91cc\u7684\u5f62\u5f0f\u53c2\u6570\u53ef\u4ee5\u8bbe\u7f6e\u4e00\u4e9b\u503c\uff0c\u4ee5\u9009\u62e9\u8fd4\u56de\u7279\u6b8a\u7684\u4ea7\u54c1\uff08\u8fd9\u91cc\u4f7f\u7528\u6a21\u677f\u800c\u6ca1\u7528\u8fd9\u79cd\u6280\u5de7\uff09\uff1a<\/p>\n<pre><code class=\"language-cpp\">template&lt;class AbstractProduct_t&gt;\nclass AbstractFactory\n{\npublic:\n    virtual AbstractProduct_t* CreateProduct() = 0;\n};<\/code><\/pre>\n<p>&emsp;&emsp;\u5728\u4e0b\u9762\u7684\u5177\u4f53Creator\u4e2d\uff0c\u6211\u4eec\u8fd4\u56de\u521b\u5efa\u7684\u4ea7\u54c1\uff1a<\/p>\n<pre><code class=\"language-cpp\">template&lt;class AbstractProduct_t, class ConcreteProduct_t&gt;\nclass ConcreteFactory\n{\npublic:\n    AbstractProduct_t* CreateProduct()\n    {\n        return new ConcreteProduct_t();\n    }\n};<\/code><\/pre>\n<h2>\u4e09\u3001\u5b9e\u4f8b<\/h2>\n<p>&emsp;&emsp;\u4e0b\u9762\u6211\u4eec\u6765\u770b\u4e00\u6bb5\u5b9e\u4f8b\uff0c\u6211\u4eec\u6709\u4e24\u4e2a\u62bd\u8c61\u4ea7\u54c1\uff1ashoes\u548cclothe\uff0c\u6211\u4eec\u7684\u5177\u4f53\u4ea7\u54c1\u662fnikeShoes\u548cuniqloClothe\u3002\u6211\u4eec\u901a\u8fc7c++\u7684\u6a21\u677f\u64cd\u4f5c\u6765\u5bf9\u5de5\u5382\u6a21\u5f0f\u505a\u4e00\u4e2a\u6539\u8fdb\uff1a<\/p>\n<pre><code class=\"language-cpp\">\/\/ \u62bd\u8c61\u7c7b\uff08\u4ea7\u54c1\uff09 01 : \u978b\u5b50\nclass Shoes\n{\npublic:\n    virtual void show() = 0;\n};\n\n\/\/ \u62bd\u8c61\u7c7b\uff08\u4ea7\u54c1\uff09 02 : \u8863\u670d\nclass Clothe\n{\npublic:\n    virtual void show() = 0;\n};\n\n\/\/ \u5177\u4f53\u4ea7\u54c1 01 : Nike Shoes\nclass NikeShoes : public Shoes\n{\npublic:\n    void show()\n    {\n        std::cout &lt;&lt; &quot;Nike Shoes&quot; &lt;&lt; std::endl;\n    }\n};\n\n\/\/ \u5177\u4f53\u4ea7\u54c1 02 : Uniqlo Clothe\nclass UniqloClothe : public Clothe\n{\npublic:\n    void show()\n    {\n        std::cout &lt;&lt; &quot;Uniqlo Clothe&quot; &lt;&lt; std::endl;\n    }\n};\n\n\/\/ \u5de5\u5382\u65b9\u6cd5\u540c\u4e0a\n\nint main()\n{\n    \/\/ \u6784\u9020\u8010\u514b\u978b\u7684\u5de5\u5382\u5bf9\u8c61\n    ConcreteFactory&lt;Shoes, NikeShoes&gt; nikeFactory;\n    \/\/ \u521b\u5efa\u8010\u514b\u978b\u5bf9\u8c61\n    Shoes* pNiKeShoes = nikeFactory.CreateProduct();\n    \/\/ \u6253\u5370\u8010\u514b\u978b\u5e7f\u544a\u8bed\n    pNiKeShoes-&gt;show();\n\n    \/\/ \u6784\u9020\u4f18\u8863\u5e93\u8863\u670d\u7684\u5de5\u5382\u5bf9\u8c61\n    ConcreteFactory&lt;Clothe, UniqloClothe&gt; uniqloFactory;\n    \/\/ \u521b\u5efa\u4f18\u8863\u5e93\u8863\u670d\u5bf9\u8c61\n    Clothe* pUniqloClothe = uniqloFactory.CreateProduct();\n    \/\/ \u6253\u5370\u4f18\u8863\u5e93\u5e7f\u544a\u8bed\n    pUniqloClothe-&gt;show();\n\n    \/\/ \u91ca\u653e\u8d44\u6e90\n    delete pNiKeShoes;\n    pNiKeShoes = NULL;\n\n    delete pUniqloClothe;\n    pUniqloClothe = NULL;\n\n    return 0;\n}<\/code><\/pre>\n<h2>\u56db\u3001\u7f3a\u9677\u4e0e\u6539\u8fdb<\/h2>\n<p>&emsp;&emsp;\u4e0a\u9762\u7684\u65b9\u6cd5\u6bd4\u8f83\u6b7b\u677f\uff0c\u5982\u679c\u60f3\u8981\u5b8c\u6210(\u670d\u88c5\u7c7b\u578b x \u54c1\u724c)\u7684\u7ec4\u5408\u5219\u9700\u8981\u4f7f\u7528\u62bd\u8c61\u5de5\u5382\u6a21\u5f0f\uff08Abstract Factory\uff09\uff0c\u8fd9\u4e2a\u6a21\u5f0f\u6211\u4eec\u5c06\u5728\u4e0b\u4e00\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u3002\u8fd9\u91cc\u6211\u4eec\u5f15\u5165\u6ce8\u518c\u673a\u7684\u673a\u5236\u6765\u521b\u5efa\u4e00\u79cd\u65b0\u7684\u5de5\u5382\u6a21\u5f0f\uff0c\u4ea7\u54c1\u6ce8\u518c\u6a21\u677f\u7c7b+\u5355\u4f8b\u5de5\u5382\u6a21\u677f\u7c7b\uff1a<br \/>\n<figure style=\"width: 901px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\"   class=\"lazyload\" data-src=\"https:\/\/cdn.swordofmorning.com\/SwordofMorning\/Article%20Images\/Design%20Pattern\/02\/Factory-Method-with-Register.png\" src=\"https:\/\/cdn.jsdelivr.net\/gh\/moezx\/cdn@3.0.2\/img\/svg\/loader\/trans.ajax-spinner-preloader.svg\" onerror=\"imgError(this)\"  width=\"901\" height=\"715\" alt=\"\u56fe2\" class=\"size-full\" \/><figcaption class=\"wp-caption-text\">\u56fe2\uff1a\u6a21\u677f\u6ce8\u518c\u673a+\u5355\u4f8b\u5de5\u5382 UML<\/figcaption><\/figure><br \/ >\n<noscript><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/cdn.swordofmorning.com\/SwordofMorning\/Article%20Images\/Design%20Pattern\/02\/Factory-Method-with-Register.png\" width=\"901\" height=\"715\" alt=\"\u56fe2\" class=\"size-full\" \/> \u56fe2\uff1a\u6a21\u677f\u6ce8\u518c\u673a+\u5355\u4f8b\u5de5\u5382 UML[\/caption]<br \/><\/noscript>\n&emsp;&emsp;\u6211\u4eec\u7684\u4ea7\u54c1\u4fdd\u6301\u4e0d\u53d8\uff1aShoes\u3001NikeShoes\u3001Clothe\u548cUniqloClothe\u3002<\/p>\n<h3>4.1 \u62bd\u8c61\u6ce8\u518c\u673a \u2013 IProductRegister<\/h3>\n<pre><code class=\"language-cpp\">template&lt;class ProductType_t&gt;\nclass IProductRegister\n{\nprivate:\n    \/\/ \u7981\u6b62\u5916\u90e8\u62f7\u8d1d\u548c\u8d4b\u503c\n    IProductRegister(const IProductRegister&amp;) = delete;\n    const IProductRegister&amp; operator=(const IProductRegister&amp;) = delete;\nprotected:\n    \/\/ \u7981\u6b62\u5916\u90e8\u6784\u9020\u4e0e\u6790\u6784\uff0c\u5141\u8bb8\u5b50\u7c7b\u5176\u4ed6\u51fd\u6570\u8c03\u7528\n    IProductRegister() {}\n    virtual ~IProductRegister() {}\npublic:\n    \/\/ \u83b7\u53d6\u62bd\u8c61\u4ea7\u54c1\u63a5\u53e3\n    virtual ProductType_t* CreateProduct() = 0;\n};<\/code><\/pre>\n<h3>4.2 \u5de5\u5382 \u2013 ProductFactory<\/h3>\n<pre><code class=\"language-cpp\">template&lt;class ProductType_t&gt;\nclass ProductFactory\n{\nprivate:\n    \/\/ \u7981\u6b62\u5916\u90e8\u6784\u9020\u4e0e\u6790\u6784\n    ProductFactory() {}\n    ~ProductFactory() {}\n\n    \/\/ \u7981\u6b62\u5916\u90e8\u62f7\u8d1d\u4e0e\u8d4b\u503c\n    ProductFactory(const ProductFactory&amp;) = delete;\n    const ProductFactory&amp; operator=(const ProductFactory&amp;) = delete;\n\n    \/\/ \u4fdd\u5b58\u5df2\u7ecf\u6ce8\u518c\u7684\u4ea7\u54c1\n    std::map&lt;std::string, IProductRegister&lt;ProductType_t&gt;*&gt; m_ProductRegistry;\n\npublic:\n    \/\/ \u6216\u5f97\u5de5\u5382\u5355\u4f8b\u3001\u5de5\u5382\u5b9e\u4f8b\u552f\u4e00\n    static ProductFactory&lt;ProductType_t&gt;&amp; Instance()\n    {\n        static ProductFactory&lt;ProductType_t&gt; instance;\n        return instance;\n    }\n\n    \/\/ \u4ea7\u54c1\u6ce8\u518c\n    void RegisterProduct(IProductRegister&lt;ProductType_t&gt;* p_register, std::string productName)\n    {\n        m_ProductRegistry[productName] = p_register;\n    }\n\n    ProductType_t* GetProduct(std::string productName)\n    {\n        \/\/ \u5df2\u6ce8\u518c\u5219\u8fd4\u56de\u4ea7\u54c1\n        if (m_ProductRegistry.count(productName) &gt; 0)\n        {\n            return m_ProductRegistry[productName]-&gt;CreateProduct();\n        }\n        std::cout &lt;&lt; &quot;product not exist&quot; &lt;&lt; std::endl;\n        return nullptr;\n    }\n};<\/code><\/pre>\n<h3>4.3 \u5177\u4f53\u6ce8\u518c\u673a \u2013 ProductRegister<\/h3>\n<pre><code class=\"language-cpp\">template&lt;class ProductType_t, class ProductImpl_t&gt;\nclass ProductRegister : public IProductRegister&lt;ProductType_t&gt;\n{\npublic:\n    \/\/ \u663e\u5f0f\u5c06\u4ea7\u54c1\u6ce8\u518c\u5230\u5de5\u5382\n    explicit ProductRegister(std::string productName)\n    {\n        ProductFactory&lt;ProductType_t&gt;::Instance().RegisterProduct(this, productName);\n    }\n\n    ProductType_t* CreateProduct()\n    {\n        return new ProductImpl_t();\n    }\n};<\/code><\/pre>\n<h3>4.4 \u5728main\u4e2d\u4f7f\u7528<\/h3>\n<pre><code class=\"language-cpp\">int main()\n{\n    \/\/ \u6ce8\u518cshoes(basic), NikeShoes(dep)\u5230\u5de5\u5382\uff0c\u53d6\u540d\u4e3aNikeShoes\n    ProductRegister&lt;Shoes, NikeShoes&gt; registeNikeShoes(&quot;NikeShoes&quot;);\n    Shoes* pNikeShoesPtr = ProductFactory&lt;Shoes&gt;::Instance().GetProduct(&quot;NikeShoes&quot;);\n    pNikeShoesPtr-&gt;show();\n\n    pNikeShoesPtr != nullptr ? delete pNikeShoes :\n        void();\n\n    \/\/ \u6ce8\u518ccolthe - uniqloClothe\u5230\u5de5\u5382\uff0c\u53d6\u540d\u4e3aUniqloClothe\n    ProductRegister&lt;Clothe, UniqloClothe&gt; resgiteUniqloClothe(&quot;UniqloClothe&quot;);\n    Clothe* pUniqloClothePtr = ProductFactory&lt;Clothe&gt;::Instance().GetProduct(&quot;UniqloClothe&quot;);\n    pUniqloClothePtr-&gt;show();\n\n    pUniqloClothePtr != nullptr ? delete pUniqloClothe :\n        void();\n\n    return 0;\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u4e00\u3001\u610f\u56fe &emsp;&emsp;\u5b9a\u4e49\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u5bf9\u8c61\u7684\u63a5\u53e3\uff0c\u8ba9\u5b50\u7c7b\u51b3\u5b9a\u5b9e\u4f8b\u5316\u54ea\u4e00\u4e2a\u5bf9\u8c61\u3002\u8bf4\u4eba\u8bdd\u5c31\u662f\uff1a\u5c06\u521b\u5efa\u5bf9\u8c61\u7684\u5de5\u4f5c\u4ea4\u7ed9\u4e00\u4e2a\u201c\u5de5 &#8230;<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[64],"tags":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/274"}],"collection":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/comments?post=274"}],"version-history":[{"count":1,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/274\/revisions"}],"predecessor-version":[{"id":453,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/posts\/274\/revisions\/453"}],"wp:attachment":[{"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/media?parent=274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/categories?post=274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/swordofmorning.com\/index.php\/wp-json\/wp\/v2\/tags?post=274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}