2009-10-13 33 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