<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    prototype詳解(轉(zhuǎn))

    http://kid-li.cnblogs.com/archive/2006/05/18/403559.html
    好不容易才找到這個(gè)牛人寫的這個(gè)文章,向作者致敬。


    Prototype原型模式是一種創(chuàng)建型設(shè)計(jì)模式,它主要面對的問題是:“某些結(jié)構(gòu)復(fù)雜的對象”的創(chuàng)建工作;由于需求的變化,這些對象經(jīng)常面臨著劇烈的變化,但是他們卻擁有比較穩(wěn)定一致的接口。感覺好像和前幾篇所說的設(shè)計(jì)模式有點(diǎn)分不清,下面我們先來回顧一下以前的幾種設(shè)計(jì)模式,予以區(qū)分,再來說說原型模式。

           Singleton單件模式解決的問題是:實(shí)體對象個(gè)數(shù)問題(這個(gè)現(xiàn)在還不太容易混)

           AbstractFactory抽象工廠模式解決的問題是:“一系列互相依賴的對象”的創(chuàng)建工作

           Builder生成器模式解決的問題是:“一些復(fù)雜對象”的創(chuàng)建工作,子對象變化較頻繁,對算法相對穩(wěn)定

          FactoryMethor工廠方法模式解決的問題是:某個(gè)對象的創(chuàng)建工作

          再回來看看今天的Prototype原型模式,它是用來解決“某些結(jié)構(gòu)復(fù)雜的對象”的創(chuàng)建工作。現(xiàn)在看看,好象還是差不多。這個(gè)問題先放在這,我們先往下看Prototype原型模式。

          《設(shè)計(jì)模式》中說道:使用原型實(shí)例指定創(chuàng)建對象的種類,然后通過拷貝這些原型來創(chuàng)建新的對象。

          此時(shí)注意:原型模式是通過拷貝自身來創(chuàng)建新的對象,這一點(diǎn)和其他創(chuàng)建型模式不相同。好,我們再來看看原型模式的結(jié)構(gòu)


           這個(gè)結(jié)構(gòu)說明原型模式的客戶端程序(ClientApp)是依賴于抽象(Prototype),而對象的具體實(shí)現(xiàn)也是依賴于抽象(Prototype)。符合設(shè)計(jì)模式原則中的依賴倒置原則——抽象不應(yīng)依賴于具體實(shí)現(xiàn),具體實(shí)現(xiàn)應(yīng)依賴于抽象。

           我們現(xiàn)在回來看看原型模式的實(shí)現(xiàn),我定義了一個(gè)場景,一個(gè)人開這一輛車在一條公路上。現(xiàn)在這件事是確定的,但不確定的有幾點(diǎn):1、人:姓名,性別,年齡;2車:什么牌子的;3公路:公路名字,長度,類型(柏油還是土路)。現(xiàn)在我們一個(gè)個(gè)實(shí)現(xiàn)。

           先來實(shí)現(xiàn)人,定義一個(gè)抽象類,AbstractDriver,具體實(shí)現(xiàn)男性(Man)和女性(Women

    public abstract class AbstractDriver

        {

            public AbstractDriver()

            {

                //

                // TODO: 在此處添加構(gòu)造函數(shù)邏輯

                //

            }

            public string name;

            public string sex;

            public int age;

            public abstract string drive();

            public abstract AbstractDriver Clone();

        }

        public class Man:AbstractDriver

        {

            public Man(string strName,int intAge)

            {

                sex = "Male";

                name = strName;

                age = intAge;

            }

            public override string drive()

            {

                return name + " is drive";

            }

            public override AbstractDriver Clone()

            {

                return (AbstractDriver)this.MemberwiseClone();

            }

        }

        public class Women:AbstractDriver

        {

            public Women(string strName,int intAge)

            {

                sex = "Female";

                name = strName;

                age = intAge;

            }

            public override string drive()

            {

                return name + " is drive";

            }

            public override AbstractDriver Clone()

            {

                return (AbstractDriver)this.MemberwiseClone();

            }

        }

        注意:抽象代碼中有一個(gè)Clone的方法,個(gè)人認(rèn)為這個(gè)方法是原型模式的一個(gè)基礎(chǔ),因?yàn)榍懊嬷v了原型模式是通過拷貝自身來創(chuàng)建新的對象。

          下面我們再來實(shí)現(xiàn)公路和汽車

          公路:

    public abstract class AbstractRoad

        {

            public AbstractRoad()

            {

                //

                // TODO: 在此處添加構(gòu)造函數(shù)邏輯

                //

            }

            public string Type;

            public string RoadName;

            public int RoadLong;

            public abstract AbstractRoad Clone();

        }

        public class Bituminous:AbstractRoad    //柏油路

        {

            public Bituminous(string strName,int intLong)

            {

                RoadName = strName;

                RoadLong = intLong;

                Type = "Bituminous";

            }

            public override AbstractRoad Clone()

            {

                return (AbstractRoad)this.MemberwiseClone();

            }

        }

        public class Cement:AbstractRoad        //水泥路

        {

            public Cement(string strName,int intLong)

            {

                RoadName = strName;

                RoadLong = intLong;

                Type = "Cement";

            }

            public override AbstractRoad Clone()

            {

                return (AbstractRoad)this.MemberwiseClone();

            }

        }

       

        汽車:

        public abstract class AbstractCar

        {

            public AbstractCar()

            {

                //

                // TODO: 在此處添加構(gòu)造函數(shù)邏輯

                //

            }

            public string OilBox;

            public string Wheel;

            public string Body;

            public abstract string Run();

            public abstract string Stop();

            public abstract AbstractCar Clone();

        }

        public class BMWCar:AbstractCar

        {

            public BMWCar()

            {

                OilBox = "BMW's OilBox";

                Wheel = "BMW's Wheel";

                Body = "BMW's body";

            }

            public override string Run()

            {

                return "BMW is running";

            }

            public override string Stop()

            {

                return "BMW is stoped";

            }

            public override AbstractCar Clone()

            {

                return (AbstractCar)this.MemberwiseClone();

            }

        }

        public class BORACar:AbstractCar

        {

            public BORACar()

            {

                OilBox = "BORA's OilBox";

                Wheel = "BORA's Wheel";

                Body = "BORA's Body";

            }

            public override string Run()

            {

                return "BORA is running";

            }

            public override string Stop()

            {

                return "BORA is stoped";

            }

            public override AbstractCar Clone()

            {

                return (AbstractCar)this.MemberwiseClone();

            }

        }

        public class VolvoCar:AbstractCar

        {

            public VolvoCar()

            {

                OilBox = "Volvo's OilBox";

                Wheel = "Volvo's Wheel";

                Body = "Volvo's Body";

            }

            public override string Run()

            {

                return "Volvo is running";

            }

            public override string Stop()

            {

                return "Volvo is stoped";

            }

            public override AbstractCar Clone()

            {

                return (AbstractCar)this.MemberwiseClone();

            }

        }

        然后我們再來看看場景,我們定義一個(gè)Manage類,在這個(gè)場景中有一個(gè)人,一輛車和一條公路,代碼實(shí)現(xiàn)如下:

    class Manage

        {

            public AbstractCar Car;

            public AbstractDriver Driver;

            public AbstractRoad Road;

            public void Run(AbstractCar car,AbstractDriver driver,AbstractRoad road)

            {

                Car = car.Clone();

                Driver = driver.Clone();

                Road = road.Clone();

            }

        }

        可以看到,在這個(gè)代碼中,場景只是依賴于那幾個(gè)抽象的類來實(shí)現(xiàn)的。最后我們再來實(shí)現(xiàn)一下客戶代碼,比如我現(xiàn)在要一輛Volvo車,一個(gè)叫“Anli”的女司機(jī),在一條叫“Road1”、長1000的柏油路上。

            static void Main(string[] args)

            {

                Manage game = new Manage();

                game.Run(new VolvoCar(),new Women("Anli",18),new Bituminous("Road1",1000));

                Console.Write("CarRun:" + game.Car.Run() + ""n");

                Console.Write("DriverName:" + game.Driver.name + ""n");

                Console.Write("DriverSex:" + game.Driver.sex + ""n");

                Console.Write("RoadName:" + game.Road.RoadName + ""n");

                Console.Write("RoadType:" + game.Road.Type + ""n");

                Console.Write("CarStop:" + game.Car.Stop() + ""n");

                Console.Read();

            }

        運(yùn)行的結(jié)果是:

        CarRun:Volvo is running

    DriverName:Anli

    DriverSex:Female

    RoadName:Road1

    RoadType:Bituminous

    CarStop:Volvo is stoped

    如果我現(xiàn)在想換成BORA車,讓我(kid-li)開,在一個(gè)水泥馬路上,我們只要更改Main函數(shù)中Run的實(shí)參。

    game.Run(new BORACar(),new Man("kid-li",24),new Cement("Road1",1000));

    運(yùn)行結(jié)果是:

    CarRun:BORA is running

    DriverName:kid-li

    DriverSex:Male

    RoadName:Road1

    RoadType:Cement

    CarStop:BORA is stoped

    這樣,經(jīng)過簡單的更改,可以實(shí)現(xiàn)實(shí)現(xiàn)細(xì)節(jié)的變化。

    現(xiàn)在我們再來看看原型模式的幾個(gè)要點(diǎn):

    1、Prototype模式同樣用于隔離類對象的使用者和具體類型(易變類)之間的耦合關(guān)系,它同樣要求這些“易變類”擁有“穩(wěn)定的接口”。

    2、Prototype模式對于“如何創(chuàng)建易變類的實(shí)體對象”采用“原型克隆”的方法來實(shí)現(xiàn),它使得我們可以非常靈活地動(dòng)態(tài)創(chuàng)建“擁有某些穩(wěn)定接口”的新對象——所需工作僅僅是注冊一個(gè)新類的對象(即原型),然后在任何需要的地方不斷地Clone。

    3、Prototype模式中的Clone方法可以利用Object類的MemberwiseClone()或者序列化來實(shí)現(xiàn)深拷貝。

    這里面我們再來說說淺拷貝和深拷貝。我想對于Prototype模式是很重要的。我覺得淺拷貝和深拷貝的關(guān)鍵區(qū)別是對于引用對象的拷貝。例如我們有一個(gè)類Class1,

    public class Class1

    {

        int a;

        int[] b;

    }

    我們用淺拷貝實(shí)現(xiàn)了兩個(gè)對象c1和c2,對于c1.a和c2.a,他們所有的內(nèi)存空間是不一樣的,但是c1.b和c2.b,由于它們是引用類型,在淺拷貝時(shí)只是拷貝了一個(gè)地址給b成員,實(shí)際上c1.b和c2.b指向同一塊內(nèi)存。

    但如果我們用深拷貝,c1.b和c2.b指向的是不同的內(nèi)存地址。那又如何實(shí)現(xiàn)深拷貝呢?我們可以利用序列化和反序列化來實(shí)現(xiàn)。

    對于淺拷貝和深考貝的問題,我的同事TerryLee曾寫過一篇文章《小議.NET中的對象拷貝》,我在這就不贅述了。

    posted on 2007-11-29 17:38 liujg 閱讀(308) 評(píng)論(1)  編輯  收藏

    評(píng)論

    # re: prototype詳解(轉(zhuǎn)) 2008-12-21 21:01 hehei

    郁悶,.NET的!,JAVA里面有MemberwiseClone這個(gè)方法么。怎么用JAVA搞原型模式呢?  回復(fù)  更多評(píng)論   


    只有注冊用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    相冊

    收藏夾

    boddiy

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 丝袜捆绑调教视频免费区| 免费在线观看的黄色网址| 国产va免费精品| 亚洲日本一线产区和二线 | 亚洲91精品麻豆国产系列在线| 国产亚洲精品高清在线| 国产又长又粗又爽免费视频| xxxxx免费视频| 久久久久国产精品免费看| 九九久久精品国产免费看小说| 最新国产成人亚洲精品影院| 亚洲一区二区影院| 亚洲国产一二三精品无码| 亚洲熟伦熟女新五十路熟妇| 在线看片无码永久免费aⅴ| 毛片a级毛片免费观看品善网| 777成影片免费观看| 久久免费美女视频| 黄视频在线观看免费| 日本特黄特色AAA大片免费| 99亚洲乱人伦aⅴ精品| 亚洲欧美国产日韩av野草社区| 亚洲另类古典武侠| 亚洲伦理一二三四| 亚洲美女aⅴ久久久91| 亚洲阿v天堂在线| 国产亚洲免费的视频看| 自拍偷自拍亚洲精品被多人伦好爽| 亚洲av午夜成人片精品电影 | 亚洲AV无码之国产精品| 亚洲精品又粗又大又爽A片| 2020国产精品亚洲综合网| 亚洲欧美第一成人网站7777 | 亚洲成人高清在线| 亚洲国产黄在线观看| 亚洲日韩中文在线精品第一| 相泽亚洲一区中文字幕| 亚洲精品无码av人在线观看| 亚洲av永久无码精品漫画 | 国产成人免费高清激情明星| 亚洲成人免费在线观看|