• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            The Programming world of Alex

            設計模式之FactoryMethod模式

            FactoryMethod模式屬于23種設計模式中的創建型模式,解決的是如何“new”的問題。

            引例:
            還是先從簡單的例子入手FactoryMethod模式吧,現在需要一個汽車測試的環境來對汽車進行測試,我們很容易會這樣設計
             1//////////////////////////////////////////////
             2//汽車類
             3class Car
             4{
             5public:
             6    void Startup(){}
             7    void Run() {}
             8    void Turn() {}
             9    void Stop() {}
            10}
            ;
            11
            12//////////////////////////////////////////////
            13//汽車測試環境
            14class CarTestFramework
            15{
            16public:
            17    void DoTest()
            18    {
            19        Car* car = new Car();
            20        car->Startup();
            21        car->Run();
            22        car->Turn();
            23        car->Stop();
            24    }

            25}
            ;


            非常簡單的設計,但是存在問題,如果我們要對紅旗車,東風車進行測試,那么怎么辦?
            有了之前那些模式的經驗,再回想下面向對象的特性。。。
            “多態”!將Car設計成為一個抽象類,DoTest里全部使用抽象類的指針來操作,那不就可以應對不同類型的汽車了嗎?
            于是有了以下的代碼:(注意DoTest的參數,這樣使用才可以讓用戶指定車輛的類型)
            //////////////////////////////////////////////
            //抽象汽車類
            class AbstractCar
            {
            public:
                
            virtual void Startup() = 0;
                
            virtual void Run() = 0;
                
            virtual void Turn() = 0;
                
            virtual void Stop() =0;
            }
            ;

            //////////////////////////////////////////////
            //具體汽車類——紅旗車
            class HongqiCar : public AbstractCar
            {
            public:
            //具體實現抽象汽車類的四個方法.
            }
            ;

            //////////////////////////////////////////////
            //汽車測試環境
            class CarTestFramework
            {
            public:
                
            void DoTest(AbstractCar* car)
                
            {
                    car
            ->Startup();
                    car
            ->Run();
                    car
            ->Turn();
                    car
            ->Stop();
                }

            }
            ;


            到此為止的設計其實還是不錯的,能夠應對不同類型的汽車變化,如果增加了新的汽車類型也完全不用修改現有代碼,只需要增加代碼就可以了
            但如果測試車輛不止一輛怎么辦?以上設計的缺陷就在于DoTest的參數,參數的個數對應于測試車輛的數量,測試數量不確定是很正常的事情。
            再想想面向對象有什么特性。。。“封裝”!用一個類專門用來封裝汽車的創建就搞定這個問題了嘛!這個類起個特別的名字就是“工廠類”。

            動機:
            軟件系統中,我們經常面對“某個對象”的創建工作;由于需求的變化,這個對象經常面臨劇烈的變化,但他有相對穩定的接口。
            為了抵抗這種變化,提出“封裝變化點”的思想,采用“封裝”機制將其“變化部分”隔離出來,從而保證“其他依賴該對象的對象”不隨需求變化而變化。

            意圖:
            定義一個用于創建對象的接口,讓子類決定實例化哪個類。Factory Method使得一個類的實例化延遲到子類。(GoF23)

            設計思路:
            還是先看看UML圖

            如果只看左邊的Product和ConcreteProduct部分,那么這就是我們的第2種設計方案。
            FatoryMethod在Product和ConcreteProduct的基礎上加上了Creator和ConcreteCreator,分別就是Factory和ConcreteFactory。Factory有個非常重要的函數CreateProduct()(就是圖中的AnOperation),它將對象的創建工作封裝了起來。

            總結:
            1.OO的“多態”。大部分的設計模式都會體現出OO的這個原則,他的作用就是“推遲實現”,將一個類的實例化推遲到子類,從而解決不同類型對象的創建問題。
            2.OO的“封裝”。工廠方法另一個重要思想,工廠類把創建工作封裝起來,這樣用戶就可以多次使用,解決了同時創建多個對象的問題。
            3.工廠方法和抽象工廠的區別:其實抽象工廠模式可以看作工廠模式的一個特例。工廠模式在工廠類中只創建一種類型的對象,如果在工廠類中擁有創建多種類型的對象的方法(比如創建引擎,創建車門,創建車燈。。。)那其實不就是之前討論的抽象工廠模式嘛?
            4.當我們創建一系列有繼承關系的類時都可以考慮使用工廠方法?;叵胫绊椖恐惺褂玫腛gre,工廠方法使用非常廣泛,幾乎所有對象都不是new出來的,Ogre提供了許許多多的CreateXX方法。

            自己做的示例代碼,僅供參考:
            AbstractFactory.h
            1#pragma once
            2#include "AbstractCar.h"
            3
            4class AbstractCarFactory
            5{
            6public:
            7    virtual AbstractCar* CreateCar() = 0;
            8}
            ;
            AbstractCar.h
             1#pragma once
             2
             3class AbstractCar
             4{
             5public:
             6    virtual void Startup() = 0;
             7    virtual void Run() = 0;
             8    virtual void Turn() = 0;
             9    virtual void Stop() = 0;
            10}
            ;
            11
            HongqiCarFactory.h
             1#pragma once
             2#include "AbstractCarFactory.h"
             3#include "HongqiCar.h"
             4
             5class HongqiCarFactory :public AbstractCarFactory
             6{
             7public:
             8    virtual AbstractCar* CreateCar()
             9    {
            10        return new HongqiCar();
            11    }

            12}
            ;
            13
            HongqiCar.h
             1#pragma once
             2#include "AbstractCar.h"
             3#include <iostream>
             4using namespace std;
             5
             6class HongqiCar : public AbstractCar
             7{
             8public:
             9    virtual void Startup()
            10    {
            11        cout<<"HongqiCar : Startup()"<<endl;
            12    }

            13    virtual void Run()
            14    {
            15        cout<<"HongqiCar : Run()"<<endl;
            16    }

            17    virtual void Turn()
            18    {
            19        cout<<"HongqiCar : Turn()"<<endl;
            20    }

            21    virtual void Stop()
            22    {
            23        cout<<"HongqiCar : Stop()"<<endl;
            24    }

            25}
            ;
            26
            Main.cpp
             1//////////////////////////////////////////////////////////////////////////
             2// FactoryMethodTest for Factory Method Test
             3//////////////////////////////////////////////////////////////////////////
             4
             5#include "stdafx.h"
             6#include "AbstractCar.h"
             7#include "AbstractCarFactory.h"
             8#include "HongqiCar.h"
             9#include "HongqiCarFactory.h"
            10#include <iostream>
            11using namespace std;
            12
            13
            14class CarTestFramework
            15{
            16public:
            17    void DoTest(AbstractCarFactory* carFactory)
            18    {
            19        AbstractCar* car1 = carFactory->CreateCar();
            20        cout<<"//////////////////////////////////////////////\n//Car1 Test\n//////////////////////////////////////////////"<<endl;
            21        car1->Startup();
            22        car1->Run();
            23        car1->Turn();
            24        car1->Stop();
            25
            26        AbstractCar* car2 = carFactory->CreateCar();
            27        cout<<"\n//////////////////////////////////////////////\n//Car2 Test\n//////////////////////////////////////////////"<<endl;
            28        car2->Startup();
            29        car2->Run();
            30        car2->Turn();
            31        car2->Stop();
            32    }

            33}
            ;
            34
            35
            36int _tmain(int argc, _TCHAR* argv[])
            37{
            38    CarTestFramework* carTestFramework = new CarTestFramework();
            39    cout<<"Test the HongqiCar"<<endl;
            40    carTestFramework->DoTest(new HongqiCarFactory());
            41
            42    return 0;
            43}

            44
            45

            posted on 2009-04-08 20:58 Alex@VCC 閱讀(1756) 評論(7)  編輯 收藏 引用 所屬分類: 設計模式

            評論

            # re: 設計模式之FactoryMethod模式 2009-04-09 09:22 yleesun

            非常感謝作者,我之前看過GOF的設計模式,當時覺得很抽象,沒有能堅持看下去。今日得見先生如此通俗易懂的描述,使我茅塞頓開,希望作者能把其他中的設計模式也能陸續分享,我將一直關注,非常感謝。  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-09 09:42 星綻紫輝

            關注中、。。。  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-09 09:53 Alex@VCC

            謝謝大家的關注,這些隨筆全是我在學習后的一些整理,如果能為大家的學習和工作帶來幫助我實在太開心了。
            有時間的話我會陸續整理其他的一些模式。

            學習設計模式關鍵是如何應用,鄙人才疏學淺,還望大家多多交流  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-12 11:12 caoji

            http://blog.csdn.net/jicao/archive/2006/07/01/861343.aspx

            看看這篇是否有啟發。

            國內寫設計模式的都太拘泥GOF的東西,其實世界很大的。

            有空再看看loki吧。  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-12 20:42 Alex@VCC

            @caoji
            我不是寫設計模式,只是做一些學習筆記罷了,呵呵
            GOF應該說還是比較經典的,對我們這些剛接觸設計模式的人來說算是一個比較好的起點吧。設計模式雖然說有著各種各樣的模式,但最重要的還是當中面向對象的思想,我覺得這點比死記各種模式重要多了

            你的那篇我仔細拜讀過了,使用函數指針也是不錯的方法:)  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-13 08:51 caoji

            GOF成書大概在1995年左右。GOF也只是提出了想法,并沒有具體的編碼實現。

            此后十來年C++的發展是非常迅速的。Boost就是一例。但是boost不好懂,不花大量時間在泛型編程上,研究boost并沒有實際意義。

            我建議是拿來主義,像boost、loki這樣的庫,用就可以了。

            但是設計模式應用非常廣泛。應該說C++還是老了些。許多新的語言特征都沒有。以至于搞個工廠模式還要用函數指針。

            設計模式的層次要高于面向對象,它教你怎么組織對象。具體問題要具體分析。我還是挺支持設計模式的  回復  更多評論   

            # re: 設計模式之FactoryMethod模式 2009-04-14 11:09 yleesun

            希望繼續更新設計模式其他的模式心得。  回復  更多評論   

            <2009年4月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            導航

            統計

            常用鏈接

            留言簿(5)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品中文字幕有码| 久久久久亚洲av毛片大| 色妞色综合久久夜夜| 91精品国产91久久久久久| 7777久久久国产精品消防器材| 国产成人久久777777| 久久精品国产亚洲欧美| 国产美女久久精品香蕉69| 亚洲精品国精品久久99热一| 污污内射久久一区二区欧美日韩 | 日日狠狠久久偷偷色综合96蜜桃 | 人妻精品久久无码区| 久久国内免费视频| 亚洲人成网站999久久久综合 | 国产69精品久久久久APP下载 | 久久99国产精品成人欧美| 9191精品国产免费久久| 伊人久久精品线影院| 狠狠精品久久久无码中文字幕| 亚洲综合精品香蕉久久网97| 久久精品国产91久久综合麻豆自制| 久久99精品久久久久婷婷| 青青青国产精品国产精品久久久久 | 99久久婷婷国产综合精品草原| 久久久久四虎国产精品| 国产毛片久久久久久国产毛片| 国产成人久久777777| 欧洲性大片xxxxx久久久| 久久久久精品国产亚洲AV无码| 亚洲人成精品久久久久| 精品蜜臀久久久久99网站| 国产高清国内精品福利99久久| 久久激情五月丁香伊人| 狠狠色丁香久久婷婷综合图片| 777午夜精品久久av蜜臀| 久久99国产精品二区不卡| 国产精品欧美久久久久无广告| 亚洲人成网站999久久久综合| 久久久精品2019免费观看| 国产精品亚洲综合专区片高清久久久| 久久久受www免费人成|