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

Joh*_*mez 15 language-agnostic design-patterns clone prototype-pattern

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

G-W*_*Wiz 18

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

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;
}
Run Code Online (Sandbox Code Playgroud)

可以在需要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;
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ler 5

排序。 Clone()为原型目的做了很多你想做的事情,但如果你需要,你可以更进一步地使用模式。请参阅Steve Yegge 的深入(而且冗长!)解释,或研究 Javascript 对象模型。