原型设计模式真的只是克隆吗?

时间:2009-10-13 21:28:59

标签: design-patterns language-agnostic clone prototype-pattern

我正在深入研究设计模式,我遇到了原型,我以前没有真正研究过。我搜索过网络和几本书,并没有一个非常好的原型示例可以找到不仅仅是克隆。原型的设计模式基本上是java和C#的语言特征吗?克隆?

3 个答案:

答案 0 :(得分:18)

原型模式远不止克隆。克隆语义更广泛,意味着一个对象实例的标量/值字段在新实例中重复,使得它们具有等效状态但占据内存中的不同位置。克隆可用于支持许多不同的需求。

Prototype模式将Clone专门用于解决将对象构造与对象使用分离的较大问题。原型语义规定,构造所需行为的新对象的唯一(或至少是受支持/首选)方法是通过克隆特定实例(称为原型实例)。这些原型实例可以存在于原型工厂中,该工厂通过在原型实例上调用Clone来实现创建新实例。可以通过依赖注入初始化原型实例。注入代码是唯一需要知道如何构建原型实例的代码,这有效地成为真正的工厂代码。

希望以下示例工厂类澄清模式的关键:

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不会随着一堆不做太多的小类而膨胀。

缺点是注入代码需要知道如何构建原型。如果在构造原型时涉及许多复杂的逻辑,那么这很脆弱。

(注意:Prototype模式不要求原型工厂上的所有方法都返回相同的类型。我只是让示例返回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;
}

答案 1 :(得分:4)

八九不离十。 Clone()为Prototype目的做了很多你想做的事情,但如果你需要的话,你可以更深入地了解这个模式。请参阅Steve Yegge's deep (and lengthy!) explanation,或研究Javascript对象模型。

答案 2 :(得分:0)

Clone()绝对是其中的一部分。我认为该模式还讨论了如何收集对象,迭代它们,找到正确的克隆对象。您还必须设置要开始的对象。