Prototype створює нові об'єкти через клонування готового шаблону замість побудови з нуля.
Яку проблему вирішує
Інколи ініціалізація об'єкта дорога або складна: підтягування конфігів, локалі, дефолтів, важкі обчислення в конструкторі. Створювати кожен екземпляр через new з повним проходом ініціалізації - повільно й надлишково, коли потрібен майже такий самий об'єкт.
Як вирішує
Один раз будуємо "еталонний" екземпляр, а далі копіюємо його через clone і донастроюємо лише те, що відрізняється. Клонування пропускає дорогу ініціалізацію.
class InvoiceTemplate
{
public function __construct(
public string $currency,
public string $locale,
) {
// expensive initialization, defaults, locale config
}
public function copy(): self
{
return clone $this;
}
}
$template = new InvoiceTemplate('USD', 'en');
$invoice = $template->copy();
$invoice->currency = 'EUR';
Зверніть увагу на clone: PHP за замовчуванням робить поверхневе (shallow) копіювання. Якщо об'єкт містить вкладені об'єкти, їх треба клонувати окремо у магічному методі __clone(), інакше копія і оригінал ділитимуть ті самі вкладені посилання.
Де застосовувати
- Об'єкти з дорогою або складною ініціалізацією, яких треба багато й майже однакових.
- Налаштування, DTO, складні об'єкти з дефолтами, які зручно "розмножувати" від шаблону.
Плюси та мінуси
- + Уникає повторення дорогої ініціалізації.
- + Створення нового екземпляра стає швидким і керованим.
- − Поверхневе клонування - пастка: вкладені об'єкти треба копіювати вручну у
__clone().
- − Надлишковий, якщо створення об'єкта дешеве: звичайний
new зрозуміліший за клонування шаблону.