程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> C#面向對象設計模式縱橫談 學習筆記6 Prototype 原型(創建型模式)

C#面向對象設計模式縱橫談 學習筆記6 Prototype 原型(創建型模式)

編輯:.NET實例教程

Prototype模式的動機

在軟件系統中,經常面臨著"某些結構復雜的對象"的創建工作;由於需求的變化,這些對象經常面臨著劇烈的變化,但是它們卻擁有比較穩定一致的接口。
如何應對這種變化?如何向"客戶程序(使用這些對象的程序)"隔離出"這些易變對象" ,從而使得"依賴這些易變對象的客戶程序"不隨著需求改變而改變?

Prototype模式的意圖

使用原型實例指定創建對象的種類,然後通過拷貝這些原型來創建新的對象。

下面看看代碼

首先我們有三個穩定的抽象基類



public abstract class NormalActor
...{
    public abstract NormalActor Clone();
}

public abstract class FlyActor
...{
    public abstract FlyActor Clone();
}

public abstract class WaterActor
...{
    public abstract WaterActor Clone();
}

這三個抽象基類是比較穩定的類

現在每個抽象基類裡都有兩個派生類,並且實現了抽象方法Clone。



public class NormalActorA : NormalActor
...{
    public override NormalActor Clone()
    ...{
        return (NormalActor)this.MemberwiseClone();
    }
}

public class NormalActorB : NormalActor
...{
    public override NormalActor Clone()
    ...{
        return (NormalActor)this.MemberwiseClone();
    }
}

public class FlyActorA : FlyActor 
...{
    public override FlyActor Clone()
    ...{
        return (FlyActor)this.MemberwiseClone();
    }
}

public class FlyAcotrB : FlyActor
...{
    public override FlyActor Clone()
    ...{
        return (WaterActor)this.MemberwiseClone();
    }
}

那麼這些派生類可以說不是很穩定的,他們可以被擴展。

那麼現在有一個GameSystem類,這個類有一個方法



public class GameSystem
...{
    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();

        FlyActor flyActor1 = flyActor.Clone();
        FlyActor flyActor2 = flyActor.Clone();

        WaterActor waterActor1 = waterActor.Clone();
        WaterActor waterActor2 = waterActor.Clone();
    }

注意在這個方法裡的參數normalActor等對象可以置為字段,這個是不重要的。重要的是我們根據給定的三個類型的實例,通過Clone方法,來創建相應的拷貝對象。

那麼當我們調用Run方法的時候



static void Main(string[] args)
...{
    GameSystem.Run(new NormalActorA(),
                    new FlyActorA(),
                    new WaterAcotrA());
}

我們通過傳入的對象的類型,使Run方法裡的創建的對象與傳入的對象一致。但是我們使用MemberwiseClone方法的時候要注意,這是一個淺拷貝對象的方法,對於一個字段都為值類型的類是適用的,但是,如果有引用類型,這樣會導致同一塊內存被兩個引用指向。我們可以在Clone方法裡對此進行處理,講對象字段新new出來,並且逐項賦值。也可以實現序列化接口,讓類序列化,那麼拷貝的時候是新生成的對象。

Prototype模式的幾個要點

  • Prototype模式同樣用於隔離類對象的使用者和具體類型(易變類)之間的耦合關系,它同樣要求這些"易變類"擁有"穩定的接口"。
  • Prototype模式對於"如何創建易變類的實體對象"采用"原型克隆"的方法來做,它使得我們可以非常靈活地動態創建"擁有某些穩定接口"的新對象--所需工作僅僅是注冊一個新類的對象(即原型),然後在任何需要的地方不斷地Clone。
  • Prototype模式中的Clone方法可以利用.Net中的Object類的MemberwiseClone()方法或者序列化來實現深拷貝。

有關創建性模式的討論

  • Singleton模式解決的是實體對象個數的問題。除了Singleton之外,其他創建型模式解決的都是new所帶來的耦合關系。
  • Factory Method, Abstract Factory, Builder都需要一個額外的工廠類來負責實例化"易變對象",而Prototype則是通過原型(一個特殊的工廠類)來克隆"易變對象"。
  • 如果遇到"易變類",起初的設計通常從FactoryMethod開始,當遇到更多的復雜變化時,再考慮重構為其他三種工廠模式( Abstract Factory,Builder , Prototype )。
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved