Действительно ли шаблон дизайна прототипа просто клон? - PullRequest
15 голосов
/ 14 октября 2009

Я глубоко изучаю шаблоны проектирования и наткнулся на прототип, который раньше не изучал. Я искал в Интернете и несколько книг, и нет действительно хорошего примера прототипа, который мог бы найти это не просто клон. Является ли шаблон проектирования прототипа в основном языковой особенностью Java и C # как клона?

Ответы [ 3 ]

18 голосов
/ 14 октября 2009

Шаблон 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;
}

Экземпляр этой фабрики можно передавать везде, где требуется IWidgetFactory. Преимущество в том, что вам не нужно связывать разные классы фабрики для каждого поведения. Фактически, для определенных типов поведения вам даже не нужна куча разных классов, если вы просто внедряете экземпляры одного и того же типа, которые по-разному инициализируются, в фабрику прототипов. В этом случае преимущество еще больше в том, что API не раздувается с кучей небольших классов, которые мало что делают.

Недостаток заключается в том, что внедряемый код должен знать, как создавать прототипы. Это хрупко, если в создании прототипов задействовано много сложной логики.

(Примечание: шаблон Prototype не требует, чтобы все методы на фабрике прототипов возвращали один и тот же тип. Я только что сделал пример, возвращающий только виджеты, потому что это демонстрирует большее преимущество использования прототипов для создания объектов для конкретного поведения, когда объекты одного типа, но инициализируются по-другому.)

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;
}
4 голосов
/ 14 октября 2009

Сорт. Clone() делает многое из того, что вы хотите для целей прототипа, но вы можете пойти гораздо дальше с шаблоном, если вам нужно. См. глубокое (и длинное!) Объяснение Стива Йегге или изучите объектную модель Javascript.

0 голосов
/ 14 октября 2009

Clone () определенно является частью этого. Я думаю, что в паттерне также говорится о том, что существуют способы сбора объектов, их перебора и поиска подходящего клонирования. Вы также должны настроить объекты для начала.

...