建立型模式:Prototype 原型模式

                                                         建立型模式:Prototype 原型模式

1、依賴關係的倒置
  1)抽象不該該依賴於實現細節,實現細節應該依賴於抽象。
  2)很差的作法:抽象A直接依賴於實現細節B
  3)oo作法:抽象A依賴於抽象B,實現細節b依賴於抽現B
 
2、動機(Motivation)
  1)在軟件系統中,常常面臨着「某此結構複雜的對象」的建立工做,因爲需求的變化,這些對象常常面臨着劇烈的變化,可是它們卻擁有比較穩定一致的接口。
  2)如何應對這種變化?如何向「客戶程序(使用這些對象的程序)」隔離出「這些易變對象」,從而使得「依賴這些易變對象的客戶程序」不隨着需求改變而改變? 設計模式

3、意圖(Intent)
  使用原型實例指定建立對象的種類,而後經過拷貝這些原型來建立新的對象。
                           ——《設計模式》GoF
                         
4、實例:遊戲場景,建立各類兵種(魂鬥鑼)
//遊戲系統,運行遊戲時建立兵種
public class GameSystem
{
  /*很差的作法,由於這裏是變化的,抽像不該依賴實現細節
  public static void Run()
  {
    //地上走的小兵(不會飛的),須要五個
    NormalActor normalActor1 = new NormalActorA();
    NormalActor normalActor2 = new NormalActorA();
    NormalActor normalActor3 = new NormalActorA();
    NormalActor normalActor4 = new NormalActorA();
    NormalActor normalActor5 = new NormalActorA();
   
    //會飛的小兵,須要二個
    FlyActor FlyActor1 = new FlyActorA();
    FlyActor FlyActor2 = new FlyActorA();
   
    //潛水的小兵,須要二個
    WaterActor WaterActor1 = new WaterActorA();
    WaterActor WaterActor2 = new WaterActorA();   
  }*/
 
  public static void Run(NormalActor normalActor,
      FlyActor flyActor, WaterActor waterActor)
  {
    NormalActor normalActor1 = normalActor.Clone();
    NormalActor normalActor2 = normalActor.Clone();
    NormalActor normalActor3 = normalActor.Clone();
    NormalActor normalActor4 = normalActor.Clone();
    NormalActor normalActor5 = normalActor.Clone();
   
    FlyActor FlyActor1 = FlyActor.Clone();
    FlyActor FlyActor2 = FlyActor.Clone();
   
    WaterActor WaterActor1 = WaterActor.Clone();
    WaterActor WaterActor2 = WaterActor.Clone();
  }
}ide

//抽象類都要提供一個克隆本身的方法
[Serializable]
public abstract class NormalActor
{
  public abstract NormalActor Clone();
}
//抽象類
[Serializable]
public abstract class FlyActor
{
  public abstract FlyActor Clone();
}
//抽象類
[Serializable]
public abstract class WaterActor
{
  public abstract WaterActor Clone();
}ui

//用序列化方式實現深拷貝所需的命名空間
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
//步兵A
[Serializable]
public class NormalActorA : NormalActor
{
  public override NormalActor Clone()
  {
    //MemberwiseClone方法是根Object目根下受保護的方法
    //該方法是按成員拷貝的方式,是個淺拷貝
    //淺拷貝會徹底拷貝值類型,而只拷貝引用類型的地址值,
    //它們指向相同的引用,所以克隆出的對象與原型有共享部分
    //通常都會使用到深拷貝,深拷貝會徹底拷貝所有數據類型
    return (NormalActorA)this.MemberwiseClone();
   
    /*下面方法實現深拷貝
    MemoryStream memoryStream = new MemoryStream();
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    //序列化
    binaryFormatter.Serialize(memoryStream, this);
    memoryStream.Position = 0;
    //反序列化
    return (NormalActor)formatter.Deserialize(memoryStream);*/
  }
}
//步兵B
[Serializable]
public class NormalActorB : NormalActor
{
  public override NormalActor Clone()
  {
    return (NormalActorB)this.MemberwiseClone();
  }
}this

//飛兵A
[Serializable]
public class FlyActorA : FlyActor
{
  public override FlyActor Clone()
  {
    return (FlyActorA)this.MemberwiseClone();
  }
}
//飛兵B
[Serializable]
public class FlyActorB : FlyActor
{
  public override FlyActor Clone()
  {
    return (FlyActorB)this.MemberwiseClone();
  }
}設計

//水兵A
[Serializable]
public class WaterActorA : WaterActor
{
  public override WaterActor Clone()
  {
    return (WaterActorA)this.MemberwiseClone();
  }
}
//水兵B
[Serializable]
public class WaterActorB : WaterActor
{
  public override WaterActor Clone()
  {
    return (WaterActorB)this.MemberwiseClone();
  }
}orm

//客戶程序
class App
{
  public static void Main()
  {
    GameSystem gameSystem = new GameSystem();
    gameSyste.Run(new NormalActor(), new FlyActorB(), new WaterActorA());
  }
}對象

5、Prototype模式的幾個要點
  1)Prototype模式一樣用於隔離類對象的使用者和具體類型(易變類)之間的耦合關係,它一樣要求這些「易變類」擁有「穩定的接口」。
  2)Prototype模式對於「如何建立易變類的實體對象」採用「原型克隆」的方法來作,它使得咱們能夠很是靈活地動態建立「擁有某些穩定接口」的新對象——所需工做僅僅是註冊一個新類的對象(即原型),而後在任何須要的地方不斷地Clone。
  3)Prototype模式中的Clone方法能夠利用.NET中的Object的MemberwiseClone()方法或者序列化來實現深拷貝。
 
6、有關建立型模式的討論
  1)Singleton模式解決的是實體對象個數的問題。除了Singleton以外,其餘建立型模式解決的都是new所帶來的耦合關係。
  2)Factory Method,Abstract Factory,Builder都須要一個額外的工廠類來負責實例化「易變對象」,而Prototype則是經過原型(一個特殊的工廠類)來克隆「易變對象」。
  3)若是遇到「易變類」,起初設計一般從Factory Method開始,當遇到更多的複雜變化時,再考慮重構爲其餘三種工廠模式(Abstract Factory,Builder,Prototype)。接口

相關文章
相關標籤/搜索