2009-10-13 70 views
15

我正在對設計模式進行深入研究,並且遇到了原型,我之前沒有真正學習過。我已經搜索了網絡和幾本書,並沒有一個真正的原型的例子,可以發現,這不僅僅是克隆。原型的設計模式基本上是java和C#的克隆語言特性嗎?原型設計模式是否真的只是克隆?

+3

模式是與語言無關的抽象,克隆是一種特定的語言成語。如果說Prototype模式是克隆習語的泛化,或者說clone是Prototype的特定語言成語,但將它與單一語言習慣用法聯繫起來的錯誤是正確的。 – 2009-10-14 09:46:51

回答

18

Prototype模式遠不止Clone。克隆語義更廣泛,這意味着一個對象實例的標量/值字段在新實例中被複制,使得它們具有等同的狀態,但在內存中佔據不同的位置。克隆可以用來支持許多不同的需求。

Prototype模式將Clone專門用於解決將對象構造與對象使用分離的較大問題。 Prototype語義表明,構造所需行爲的新對象的唯一(或至少支持/首選)方法是克隆特定實例,即原型實例。這些原型實例可以存在於原型工廠中,該原型工廠通過在原型實例上調用克隆來創建新實例。原型實例可以通過依賴注入來初始化。注入代碼是唯一需要知道如何構建原型實例的代碼,並且這有效地成爲真正的工廠代碼。

希望下面的例子工廠類闡明瞭圖案的關鍵所在:

public class PrototypeWidgetFactory : IWidgetFactory 
{ 
    public PrototypeWidgetFactory(PrototypeWidget scenarioA, PrototypeWidget scenarioB, PrototypeWidget scenarioC) 
    { 
    _scenarioA = scenarioA; 
    _scenarioB = scenarioB; 
    _scenarioC = scenarioC; 
    } 

    public Widget GetForScenarioA() { return _scenarioA.Clone(); } 
    public Widget GetForScenarioB() { return _scenarioB.Clone(); } 
    public Widget GetForScenarioC() { return _scenarioC.Clone(); } 

    private PrototypeWidgetFactory _scenarioA; 
    private PrototypeWidgetFactory _scenarioB; 
    private PrototypeWidgetFactory _scenarioC; 
} 

此工廠的實例可以在任何需要的IWidgetFactory傳遞。好處是你不需要爲每個行爲使用一堆不同的工廠類。事實上,對於某些類型的行爲,如果只是將不同初始化的實例注入到原型工廠中,則不需要一堆不同的類。在這種情況下,優勢更大,因爲API不會因一堆不太多的小類而膨脹。

缺點是注入代碼需要知道如何構建原型。如果在構建原型時涉及很多複雜的邏輯,那麼這很脆弱。 (注意:原型模式並不要求原型工廠的所有方法都返回相同的類型,我只是讓這個例子只返回Widgets,因爲這表明使用原型構造特定行爲對象的更大優勢,對象是一種類型,但初始化方式不同。)

public class PrototypeDomainFactory : IDomainFactory 
{ 
    public PrototypeDomainFactory(PrototypePerson personPrototype, PrototypeCompany companyPrototype, PrototypeWidget widgetPrototype) 
    { 
    _personPrototype = personPrototype; 
    _companyPrototype = companyPrototype; 
    _widgetPrototype = widgetPrototype; 
    } 

    public Person GetPerson() { return _personPrototype.Clone(); } 
    public Company GetCompany() { return _companyPrototype.Clone(); } 
    public Widget GetWidget() { return _widgetPrototype.Clone(); } 

    private PrototypePerson _personPrototype; 
    private PrototypeCompany _companyPrototype; 
    private PrototypeWidget _widgetPrototype; 
} 
0

Clone()肯定是它的一部分。我認爲該模式還提到了收集對象的方法,遍歷它們並找到合適的方法進行克隆。您還必須設置開始的對象。

4

Sorta。 Clone()做了很多你想要的Prototype用途,但如果需要的話,你可以進一步使用這個模式。請參閱Steve Yegge's deep (and lengthy!) explanation,或研究Javascript對象模型。

+1

這不是原型 - (雖然它是絕對相關的) - 他稱之爲屬性模式。在JavaScript中,使用「原型」這個詞來描述其中的一部分,而克隆是絕對涉及的,但我仍然認爲它們是不同的東西。 GoF中的原型並不討論動態屬性的概念。 – 2009-10-13 21:41:25

+0

這是一個公平點。我一直認爲Prototype包含諸如動態屬性和迭代之類的東西,只是因爲如果它不*它*基本上是Clone(),那看起來很蹩腳。 – 2009-10-13 21:46:33

+0

哇,感謝您發佈該博客條目。非常好的閱讀。從閱讀中我學到了很多東西。我同意這不是在GoF書中描述的原型模式。 – 2009-10-13 22:27:25