Franky's LIFE

          Anything... ...

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            53 隨筆 :: 87 文章 :: 6 評論 :: 0 Trackbacks
          Prototype 原 型模式是一種創(chuàng)建型設計模式,它主要面對的問題是:“某些結構復雜的對象”的創(chuàng)建工作;由于需求的變化,這些對象經(jīng)常面臨著劇烈的變化,但是他們卻擁有比 較穩(wěn)定一致的接口。感覺好像和前幾篇所說的設計模式有點分不清,下面我們先來回顧一下以前的幾種設計模式,予以區(qū)分,再來說說原型模式。

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

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

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

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

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

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

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


          ??????
          這個結構說明原型模式的客戶端程序( ClientApp )是依賴于抽象( Prototype ),而對象的具體實現(xiàn)也是依賴于抽象( Prototype )。符合設計模式原則中的依賴倒置原則——抽象不應依賴于具體實現(xiàn),具體實現(xiàn)應依賴于抽象。

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

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

          public abstract class AbstractDriver

          ??? {

          ??????? public AbstractDriver()

          ??????? {

          ??????????? //

          ??????????? // TODO: 在此處添加構造函數(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();

          ??????? }

          ??? }

          ??? 注意:抽象代碼中有一個Clone的方法,個人認為這個方法是原型模式的一個基礎,因為前面講了 原型模式是通過拷貝自身來創(chuàng)建新的對象。

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

          ????? 公路:

          public abstract class AbstractRoad

          ??? {

          ??????? public AbstractRoad()

          ??????? {

          ??????????? //

          ??????????? // TODO: 在此處添加構造函數(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: 在此處添加構造函數(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();

          ??????? }

          ??? }

          ??? 然后我們再來看看場景,我們定義一個Manage類,在這個場景中有一個人,一輛車和一條公路,代碼實現(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();

          ??????? }

          ??? }

          ??? 可以看到,在這個代碼中,場景只是依賴于那幾個抽象的類來實現(xiàn)的。最后我們再來實現(xiàn)一下客戶代碼,比如我現(xiàn)在要一輛Volvo車,一個叫“Anli”的女司機,在一條叫“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();

          ??????? }

          ??? 運行的結果是:

          ??? CarRun:Volvo is running

          DriverName:Anli

          DriverSex:Female

          RoadName:Road1

          RoadType:Bituminous

          CarStop:Volvo is stoped

          ?

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

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

          運行結果是:

          CarRun:BORA is running

          DriverName:kid-li

          DriverSex:Male

          RoadName:Road1

          RoadType:Cement

          CarStop:BORA is stoped

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

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

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

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

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

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

          public class Class1

          {

          ??? int a;

          ??? int[] b;

          }

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

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

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

          posted on 2007-03-19 20:47 Franky 閱讀(137) 評論(0)  編輯  收藏 所屬分類: IT知識
          主站蜘蛛池模板: 通许县| 长治市| 三门县| 宝清县| 昌江| 海安县| 甘德县| 黔江区| 河池市| 华阴市| 宿州市| 久治县| 昭通市| 富蕴县| 祥云县| 出国| 朝阳县| 德令哈市| 定结县| 乐陵市| 辛集市| 洛扎县| 项城市| 静乐县| 班戈县| 通州市| 青河县| 拜泉县| 万山特区| 康平县| 潮安县| 固阳县| 清丰县| 武定县| 平遥县| 四平市| 嘉定区| 华安县| 乐清市| 南昌市| 拜泉县|