乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      原型模式(Prototype Pattern)

       漂在北方的狼 2007-03-28

      一、 原型(Prototype)模式

      原型模式的用意是:通過(guò)給出一個(gè)原型對(duì)象來(lái)指明所要?jiǎng)?chuàng)建的對(duì)象類型,然后用復(fù)制這個(gè)原型對(duì)象的辦法創(chuàng)建出更多的同類型對(duì)象。

      從孫大圣的手段談起

      孫悟空在與黃風(fēng)怪的戰(zhàn)斗中,"使一個(gè)身外身的手段:把毫毛揪下一把,用口嚼得粉碎,望上一噴,叫聲‘變‘,變有百十個(gè)行者,都是一樣得打扮,各執(zhí)一根鐵棒,把那怪圍在空中。"換而言之,孫悟空可以根據(jù)自己的形象,復(fù)制出很多"身外身"來(lái)。

      老孫這種身外身的手段在面向?qū)ο笤O(shè)計(jì)領(lǐng)域里叫原型(Prototype)模式。

      C#對(duì)原型模式的支持

      在C#里面,我們可以很容易的通過(guò)Clone()方法實(shí)現(xiàn)原型模式。任何類,只要想支持克隆,必須實(shí)現(xiàn)C#中的ICloneable接口。 ICloneable接口中有一Clone方法,可以在類中復(fù)寫實(shí)現(xiàn)自定義的克隆方法??寺〉膶?shí)現(xiàn)方法有兩種:淺拷貝(shallow copy)與深拷貝(deep copy)。

      (以下摘自:《.NET框架程序設(shè)計(jì)(修訂版)》,李建忠譯)淺拷貝是指當(dāng)對(duì)象的字段值被拷貝時(shí),字段引用的對(duì)象不會(huì)被拷貝。例如,如果一個(gè)對(duì)象有 一個(gè)指向字符串的字段,并且我們對(duì)該對(duì)象做了一個(gè)淺拷貝,那么兩個(gè)對(duì)象將引用同一個(gè)字符串。而深拷貝是對(duì)對(duì)象實(shí)例中字段引用的對(duì)象也進(jìn)行拷貝的一種方式, 所以如果一個(gè)對(duì)象有一個(gè)指向字符串的字段,并且我們對(duì)該對(duì)象做了一個(gè)深拷貝的話,我們將創(chuàng)建一個(gè)新的對(duì)象和一個(gè)新的字符串--新對(duì)象將引用新字符串。需要 注意的是執(zhí)行深拷貝后,原來(lái)的對(duì)象和新創(chuàng)建的對(duì)象不會(huì)共享任何東西;改變一個(gè)對(duì)象對(duì)另外一個(gè)對(duì)象沒(méi)有任何影響。


      二、 Prototype模式的結(jié)構(gòu):

       

      客戶(Client)角色:客戶類提出創(chuàng)建對(duì)象的請(qǐng)求。
      抽象原型(Prototype)角色:這是一個(gè)抽象角色,通常由一個(gè)C#接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體原型類所需的接口。在C#中,抽象原型角色通常實(shí)現(xiàn)了ICloneable接口。
      具體原型(Concrete Prototype)角色:被復(fù)制的對(duì)象。此角色需要實(shí)現(xiàn)抽象原型角色所要求的接口。


      三、 程序舉例:

      下面的程序給出了一個(gè)示意性的實(shí)現(xiàn):

       

      // Prototype pattern -- Structural example  
      using System;

      // "Prototype"
      abstract class Prototype
      {
        
      // Fields
        private string id;

        
      // Constructors
        public Prototype( string id )
        
      {
          
      this.id = id;
        }


        
      public string Id
        
      {
          
      getreturn id; }
        }


        
      // Methods
        abstract public Prototype Clone();
      }


      // "ConcretePrototype1"
      class ConcretePrototype1 : Prototype
      {
        
      // Constructors
        public ConcretePrototype1( string id ) : base ( id ) {}

        
      // Methods
        override public Prototype Clone()
        
      {
          
      // Shallow copy
          return (Prototype)this.MemberwiseClone();
        }

      }


      // "ConcretePrototype2"
      class ConcretePrototype2 : Prototype
      {
        
      // Constructors
        public ConcretePrototype2( string id ) : base ( id ) {}

        
      // Methods
        override public Prototype Clone()
        
      {
          
      // Shallow copy
          return (Prototype)this.MemberwiseClone();
        }

      }


      /// 
      /// Client test
      /// 

      class Client
      {
        
      public static void Main( string[] args )
        
      {
          
      // Create two instances and clone each
          ConcretePrototype1 p1 = new ConcretePrototype1( "I" );
          ConcretePrototype1 c1 
      = (ConcretePrototype1)p1.Clone();
          Console.WriteLine( 
      "Cloned: {0}", c1.Id );

          ConcretePrototype2 p2 
      = new ConcretePrototype2( "II" );
          ConcretePrototype2 c2 
      = (ConcretePrototype2)p2.Clone();
          Console.WriteLine( 
      "Cloned: {0}", c2.Id );
        }

      }

       

      這個(gè)例子實(shí)現(xiàn)了一個(gè)淺拷貝。其中MemberwiseClone()方法是Object類的一個(gè)受保護(hù)方法,實(shí)現(xiàn)了對(duì)象的淺拷貝。如果希望實(shí)現(xiàn)一個(gè)深拷貝,應(yīng)該實(shí)現(xiàn)ICloneable接口,并自己編寫ICloneable的Clone接口方法。


      四、 帶Prototype Manager的原型模式

      原型模式的第二種形式是帶原型管理器的原型模式,其UML圖如下:

       

      客戶(Client)角色:客戶端類向原型管理器提出創(chuàng)建對(duì)象的請(qǐng)求。
      抽象原型(Prototype)角色:這是一個(gè)抽象角色,通常由一個(gè)C#接口或抽象類實(shí)現(xiàn)。此角色給出所有的具體原型類所需的接口。在C#中,抽象原型角色通常實(shí)現(xiàn)了ICloneable接口。
      具體原型(Concrete Prototype)角色:被復(fù)制的對(duì)象。此角色需要實(shí)現(xiàn)抽象的原型角色所要求的接口。
      原型管理器(Prototype Manager)角色:創(chuàng)建具體原型類的對(duì)象,并記錄每一個(gè)被創(chuàng)建的對(duì)象。


      下面這個(gè)例子演示了在原型管理器中存儲(chǔ)用戶預(yù)先定義的顏色原型,客戶通過(guò)原型管理器克隆顏色對(duì)象。

       

      // Prototype pattern -- Real World example  
      using System;
      using System.Collections;

      // "Prototype"
      abstract class ColorPrototype
      {
        
      // Methods
        public abstract ColorPrototype Clone();
      }


      // "ConcretePrototype"
      class Color : ColorPrototype
      {
        
      // Fields
        private int red, green, blue;

        
      // Constructors
        public Color( int red, int green, int blue)
        
      {
          
      this.red = red;
          
      this.green = green;
          
      this.blue = blue;
        }


        
      // Methods
        public override ColorPrototype Clone()
        
      {
          
      // Creates a ‘shallow copy‘
          return (ColorPrototype) this.MemberwiseClone();
        }


        
      public void Display()
        
      {
          Console.WriteLine( 
      "RGB values are: {0},{1},{2}",
            red, green, blue );
        }

      }


      // Prototype manager
      class ColorManager
      {
        
      // Fields
        Hashtable colors = new Hashtable();

        
      // Indexers
        public ColorPrototype thisstring name ]
        
      {
          
      getreturn (ColorPrototype)colors[ name ]; }
          
      set{ colors.Add( name, value ); }
        }

      }


      /// 
      ///  PrototypeApp test
      /// 

      class PrototypeApp
      {
        
      public static void Main( string[] args )
        
      {
          ColorManager colormanager 
      = new ColorManager();

          
      // Initialize with standard colors
          colormanager[ "red" ] = new Color( 25500 );
          colormanager[ 
      "green" ] = new Color( 02550 );
          colormanager[ 
      "blue" ] = new Color( 00255 );

          
      // User adds personalized colors
          colormanager[ "angry" ] = new Color( 255540 );
          colormanager[ 
      "peace" ] = new Color( 128211128 );
          colormanager[ 
      "flame" ] = new Color( 2113420 );

          
      // User uses selected colors
          string colorName = "red";
          Color c1 
      = (Color)colormanager[ colorName ].Clone();
          c1.Display();

          colorName 
      = "peace";
          Color c2 
      = (Color)colormanager[ colorName ].Clone();
          c2.Display();

          colorName 
      = "flame";
          Color c3 
      = (Color)colormanager[ colorName ].Clone();
          c3.Display();
        }

      }

       



      五、 淺拷貝與深拷貝

      下面給出淺拷貝與深拷貝的兩個(gè)例子,例子使用了ICloneable接口。C#中的數(shù)組是引用型的變量,我們通過(guò)數(shù)組來(lái)進(jìn)行演示:

      淺拷貝:

       

      using System;

      class ShallowCopy : ICloneable
      {
        
      public int[] v = {1,2,3};

        
      public Object Clone()
        
      {
          
      return this.MemberwiseClone();
        }


        
      public void Display()
        
      {
          
      foreach(int i in v)
            Console.Write( i 
      + "");
          Console.WriteLine();
        }

      }


      class Client
      {
        
      public static void Main()
        
      {
          ShallowCopy sc1 
      = new ShallowCopy();
          ShallowCopy sc2 
      = (ShallowCopy)sc1.Clone();
          sc1.v[
      0= 9;

          sc1.Display();
          sc2.Display();
        }

      }

       


      ShallowCopy對(duì)象實(shí)現(xiàn)了一個(gè)淺拷貝,因此當(dāng)對(duì)sc1進(jìn)行克隆時(shí),其字段v并沒(méi)有克隆,這導(dǎo)致sc1與sc2的字段v都指向了同一個(gè)v,因此,當(dāng)修改了sc1的v[0]后,sc2的v[0]也發(fā)生了變化。

      深拷貝:

       

      using System;

      class DeepCopy : ICloneable
      {
        
      public int[] v = {1,2,3};

        
      // 默認(rèn)構(gòu)造函數(shù)
        public DeepCopy()
        
      {
        }


        
      // 供Clone方法調(diào)用的私有構(gòu)造函數(shù)
        private DeepCopy(int[] v)
        
      {
          
      this.v = (int[])v.Clone();
        }


        
      public Object Clone()
        
      {
          
      // 構(gòu)造一個(gè)新的DeepCopy對(duì)象,構(gòu)造參數(shù)為
          
      // 原有對(duì)象中使用的 v 
          return new DeepCopy(this.v);
        }


        
      public void Display()
        
      {
          
      foreach(int i in v)
            Console.Write( i 
      + "");
          Console.WriteLine();
        }

      }


      class Client
      {
        
      public static void Main()
        
      {
          DeepCopy dc1 
      = new DeepCopy();
          DeepCopy dc2 
      = (DeepCopy)dc1.Clone();
          dc1.v[
      0= 9;

          dc1.Display();
          dc2.Display();
        }

      }

       


      這次在克隆的時(shí)候,不但克隆對(duì)象本身,連里面的數(shù)組字段一并克隆。因此,最終打印出來(lái)的dc1與dc2不同。


      六、 Prototype模式的優(yōu)點(diǎn)與缺點(diǎn)

      Prototype模式的優(yōu)點(diǎn)包括

      1、Prototype模式允許動(dòng)態(tài)增加或減少產(chǎn)品類。由于創(chuàng)建產(chǎn)品類實(shí)例的方法是產(chǎn)批類內(nèi)部具有的,因此增加新產(chǎn)品對(duì)整個(gè)結(jié)構(gòu)沒(méi)有影響。

      2、Prototype模式提供了簡(jiǎn)化的創(chuàng)建結(jié)構(gòu)。工廠方法模式常常需要有一個(gè)與產(chǎn)品類等級(jí)結(jié)構(gòu)相同的等級(jí)結(jié)構(gòu),而Prototype模式就不需要這樣。

      3、Portotype模式具有給一個(gè)應(yīng)用軟件動(dòng)態(tài)加載新功能的能力。由于Prototype的獨(dú)立性較高,可以很容易動(dòng)態(tài)加載新功能而不影響老系統(tǒng)。

      4、產(chǎn)品類不需要非得有任何事先確定的等級(jí)結(jié)構(gòu),因?yàn)镻rototype模式適用于任何的等級(jí)結(jié)構(gòu)。


      Prototype模式的缺點(diǎn):

      Prototype模式的最主要缺點(diǎn)就是每一個(gè)類必須配備一個(gè)克隆方法。而且這個(gè)克隆方法需要對(duì)類的功能進(jìn)行通盤考慮,這對(duì)全新的類來(lái)說(shuō)不是很難,但對(duì)已有的類進(jìn)行改造時(shí),不一定是件容易的事。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多