• <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

            設(shè)計(jì)模式之FactoryMethod模式

            FactoryMethod模式屬于23種設(shè)計(jì)模式中的創(chuàng)建型模式,解決的是如何“new”的問(wèn)題。

            引例:
            還是先從簡(jiǎn)單的例子入手FactoryMethod模式吧,現(xiàn)在需要一個(gè)汽車(chē)測(cè)試的環(huán)境來(lái)對(duì)汽車(chē)進(jìn)行測(cè)試,我們很容易會(huì)這樣設(shè)計(jì)
             1//////////////////////////////////////////////
             2//汽車(chē)類(lèi)
             3class Car
             4{
             5public:
             6    void Startup(){}
             7    void Run() {}
             8    void Turn() {}
             9    void Stop() {}
            10}
            ;
            11
            12//////////////////////////////////////////////
            13//汽車(chē)測(cè)試環(huán)境
            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}
            ;


            非常簡(jiǎn)單的設(shè)計(jì),但是存在問(wèn)題,如果我們要對(duì)紅旗車(chē),東風(fēng)車(chē)進(jìn)行測(cè)試,那么怎么辦?
            有了之前那些模式的經(jīng)驗(yàn),再回想下面向?qū)ο蟮奶匦浴!!?br>“多態(tài)”!將Car設(shè)計(jì)成為一個(gè)抽象類(lèi),DoTest里全部使用抽象類(lèi)的指針來(lái)操作,那不就可以應(yīng)對(duì)不同類(lèi)型的汽車(chē)了嗎?
            于是有了以下的代碼:(注意DoTest的參數(shù),這樣使用才可以讓用戶指定車(chē)輛的類(lèi)型)
            //////////////////////////////////////////////
            //抽象汽車(chē)類(lèi)
            class AbstractCar
            {
            public:
                
            virtual void Startup() = 0;
                
            virtual void Run() = 0;
                
            virtual void Turn() = 0;
                
            virtual void Stop() =0;
            }
            ;

            //////////////////////////////////////////////
            //具體汽車(chē)類(lèi)——紅旗車(chē)
            class HongqiCar : public AbstractCar
            {
            public:
            //具體實(shí)現(xiàn)抽象汽車(chē)類(lèi)的四個(gè)方法.
            }
            ;

            //////////////////////////////////////////////
            //汽車(chē)測(cè)試環(huán)境
            class CarTestFramework
            {
            public:
                
            void DoTest(AbstractCar* car)
                
            {
                    car
            ->Startup();
                    car
            ->Run();
                    car
            ->Turn();
                    car
            ->Stop();
                }

            }
            ;


            到此為止的設(shè)計(jì)其實(shí)還是不錯(cuò)的,能夠應(yīng)對(duì)不同類(lèi)型的汽車(chē)變化,如果增加了新的汽車(chē)類(lèi)型也完全不用修改現(xiàn)有代碼,只需要增加代碼就可以了
            但如果測(cè)試車(chē)輛不止一輛怎么辦?以上設(shè)計(jì)的缺陷就在于DoTest的參數(shù),參數(shù)的個(gè)數(shù)對(duì)應(yīng)于測(cè)試車(chē)輛的數(shù)量,測(cè)試數(shù)量不確定是很正常的事情。
            再想想面向?qū)ο笥惺裁刺匦浴!!?#8220;封裝”!用一個(gè)類(lèi)專(zhuān)門(mén)用來(lái)封裝汽車(chē)的創(chuàng)建就搞定這個(gè)問(wèn)題了嘛!這個(gè)類(lèi)起個(gè)特別的名字就是“工廠類(lèi)”。

            動(dòng)機(jī):
            軟件系統(tǒng)中,我們經(jīng)常面對(duì)“某個(gè)對(duì)象”的創(chuàng)建工作;由于需求的變化,這個(gè)對(duì)象經(jīng)常面臨劇烈的變化,但他有相對(duì)穩(wěn)定的接口。
            為了抵抗這種變化,提出“封裝變化點(diǎn)”的思想,采用“封裝”機(jī)制將其“變化部分”隔離出來(lái),從而保證“其他依賴該對(duì)象的對(duì)象”不隨需求變化而變化。

            意圖:
            定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類(lèi)決定實(shí)例化哪個(gè)類(lèi)。Factory Method使得一個(gè)類(lèi)的實(shí)例化延遲到子類(lèi)。(GoF23)

            設(shè)計(jì)思路:
            還是先看看UML圖

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

            總結(jié):
            1.OO的“多態(tài)”。大部分的設(shè)計(jì)模式都會(huì)體現(xiàn)出OO的這個(gè)原則,他的作用就是“推遲實(shí)現(xiàn)”,將一個(gè)類(lèi)的實(shí)例化推遲到子類(lèi),從而解決不同類(lèi)型對(duì)象的創(chuàng)建問(wèn)題。
            2.OO的“封裝”。工廠方法另一個(gè)重要思想,工廠類(lèi)把創(chuàng)建工作封裝起來(lái),這樣用戶就可以多次使用,解決了同時(shí)創(chuàng)建多個(gè)對(duì)象的問(wèn)題。
            3.工廠方法和抽象工廠的區(qū)別:其實(shí)抽象工廠模式可以看作工廠模式的一個(gè)特例。工廠模式在工廠類(lèi)中只創(chuàng)建一種類(lèi)型的對(duì)象,如果在工廠類(lèi)中擁有創(chuàng)建多種類(lèi)型的對(duì)象的方法(比如創(chuàng)建引擎,創(chuàng)建車(chē)門(mén),創(chuàng)建車(chē)燈。。。)那其實(shí)不就是之前討論的抽象工廠模式嘛?
            4.當(dāng)我們創(chuàng)建一系列有繼承關(guān)系的類(lèi)時(shí)都可以考慮使用工廠方法。回想之前項(xiàng)目中使用的Ogre,工廠方法使用非常廣泛,幾乎所有對(duì)象都不是new出來(lái)的,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 閱讀(1754) 評(píng)論(7)  編輯 收藏 引用 所屬分類(lèi): 設(shè)計(jì)模式

            評(píng)論

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-09 09:22 yleesun

            非常感謝作者,我之前看過(guò)GOF的設(shè)計(jì)模式,當(dāng)時(shí)覺(jué)得很抽象,沒(méi)有能堅(jiān)持看下去。今日得見(jiàn)先生如此通俗易懂的描述,使我茅塞頓開(kāi),希望作者能把其他中的設(shè)計(jì)模式也能陸續(xù)分享,我將一直關(guān)注,非常感謝。  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-09 09:42 星綻紫輝

            關(guān)注中、。。。  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-09 09:53 Alex@VCC

            謝謝大家的關(guān)注,這些隨筆全是我在學(xué)習(xí)后的一些整理,如果能為大家的學(xué)習(xí)和工作帶來(lái)幫助我實(shí)在太開(kāi)心了。
            有時(shí)間的話我會(huì)陸續(xù)整理其他的一些模式。

            學(xué)習(xí)設(shè)計(jì)模式關(guān)鍵是如何應(yīng)用,鄙人才疏學(xué)淺,還望大家多多交流  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-12 11:12 caoji

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

            看看這篇是否有啟發(fā)。

            國(guó)內(nèi)寫(xiě)設(shè)計(jì)模式的都太拘泥GOF的東西,其實(shí)世界很大的。

            有空再看看loki吧。  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-12 20:42 Alex@VCC

            @caoji
            我不是寫(xiě)設(shè)計(jì)模式,只是做一些學(xué)習(xí)筆記罷了,呵呵
            GOF應(yīng)該說(shuō)還是比較經(jīng)典的,對(duì)我們這些剛接觸設(shè)計(jì)模式的人來(lái)說(shuō)算是一個(gè)比較好的起點(diǎn)吧。設(shè)計(jì)模式雖然說(shuō)有著各種各樣的模式,但最重要的還是當(dāng)中面向?qū)ο蟮乃枷耄矣X(jué)得這點(diǎn)比死記各種模式重要多了

            你的那篇我仔細(xì)拜讀過(guò)了,使用函數(shù)指針也是不錯(cuò)的方法:)  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-13 08:51 caoji

            GOF成書(shū)大概在1995年左右。GOF也只是提出了想法,并沒(méi)有具體的編碼實(shí)現(xiàn)。

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

            我建議是拿來(lái)主義,像boost、loki這樣的庫(kù),用就可以了。

            但是設(shè)計(jì)模式應(yīng)用非常廣泛。應(yīng)該說(shuō)C++還是老了些。許多新的語(yǔ)言特征都沒(méi)有。以至于搞個(gè)工廠模式還要用函數(shù)指針。

            設(shè)計(jì)模式的層次要高于面向?qū)ο螅棠阍趺唇M織對(duì)象。具體問(wèn)題要具體分析。我還是挺支持設(shè)計(jì)模式的  回復(fù)  更多評(píng)論   

            # re: 設(shè)計(jì)模式之FactoryMethod模式 2009-04-14 11:09 yleesun

            希望繼續(xù)更新設(shè)計(jì)模式其他的模式心得。  回復(fù)  更多評(píng)論   

            <2010年6月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(5)

            隨筆分類(lèi)

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            欧美黑人激情性久久| 久久66热人妻偷产精品9| 久久精品麻豆日日躁夜夜躁| 精品久久久久国产免费| 亚洲中文字幕久久精品无码APP| 久久精品国产半推半就| 伊人久久亚洲综合影院| 精品国产91久久久久久久| 人妻无码精品久久亚瑟影视 | 久久精品亚洲一区二区三区浴池| 国产精品99久久不卡| 久久久一本精品99久久精品66| 久久夜色撩人精品国产小说| 精品免费tv久久久久久久| 久久久久久久波多野结衣高潮| 久久精品成人欧美大片| 久久99精品国产一区二区三区 | 久久精品国产只有精品66| 久久婷婷成人综合色综合| 久久亚洲sm情趣捆绑调教 | 久久久久久久综合日本亚洲 | 蜜桃麻豆WWW久久囤产精品| 精品久久久久久国产三级| 色综合久久最新中文字幕| 久久亚洲美女精品国产精品| 久久精品国产99国产精品导航| 欧美日韩精品久久久久| 久久精品国产精品亚洲下载| 香蕉久久一区二区不卡无毒影院| 精品久久久无码人妻中文字幕豆芽| 久久人妻少妇嫩草AV蜜桃| 狠狠色丁香婷婷久久综合| 色综合久久天天综线观看| 欧美与黑人午夜性猛交久久久| 人人狠狠综合久久亚洲| 久久青青草原精品国产不卡| 久久中文精品无码中文字幕| 久久综合色区| 国产成人综合久久精品红| 精品久久人人爽天天玩人人妻| 人妻无码精品久久亚瑟影视|