Prototype

Паттерн, который создаёт объекты не через конструктор, а клонированием готового образца-прототипа.

Prototype создаёт новые объекты, копируя существующий объект-прототип, вместо создания с нуля.

Какую задачу решает

Иногда настроить объект дорого или сложно: много полей, тяжёлая инициализация, данные пришли из сети. Если нужен почти такой же объект, проще склонировать готовый и слегка изменить, чем собирать заново. Plus, клонирование не требует знать конкретный класс прототипа.

Идея и реализация

В Python инструмент уже встроен — модуль copy. Важно различать поверхностную (copy.copy) и глубокую (copy.deepcopy) копию: первая копирует только верхний уровень и делит вложенные объекты, вторая копирует всё дерево.

import copy


class Document:
    def __init__(self, title, tags):
        self.title = title
        self.tags = tags        # список — вложенный объект

    def clone(self):
        return copy.deepcopy(self)


original = Document("Шаблон", ["draft"])
copy1 = original.clone()
copy1.title = "Отчёт Q1"
copy1.tags.append("final")      # меняем копию

print("ориг:", original.title, original.tags)
print("копия:", copy1.title, copy1.tags)

Вывод:

ориг: Шаблон ['draft']
копия: Отчёт Q1 ['draft', 'final']

Благодаря deepcopy список tags у копии независим: добавление "final" не затронуло оригинал. Если бы мы использовали поверхностную копию, оба объекта делили бы один список — и оригинал тоже получил бы "final". Это самая частая ловушка Prototype.

Shallow против deep

КопияЧто копируетРиск
copy.copy (shallow)только верхний уровеньвложенные объекты общие — мутация одного задевает другой
copy.deepcopyвсё дерево объектовдороже по времени и памяти

Плюсы и минусы

  • Плюс: создание объекта без знания его конкретного класса и без дорогой повторной инициализации.
  • Минус: глубокое копирование объектов со ссылками друг на друга (циклами) бывает хитрым; нужно следить за shallow/deep.

Где встречается

Редакторы (копирование фигур/слоёв), игровые сущности (клонировать «болванку» врага), кеши заранее настроенных объектов, прототипирование конфигов. В JavaScript идея прототипов вообще встроена в язык.

Итог

  • Prototype = создание через клонирование образца.
  • В Python — copy.deepcopy; различайте shallow и deep копии.
  • Полезен, когда настройка объекта дороже его копирования.
Проверьте себя
1. Как Prototype создаёт новые объекты?
AЧерез конструктор с нуля
BКопированием существующего объекта-прототипа
CЧерез глобальную фабрику
DЧерез наследование
2. В чём опасность поверхностной (shallow) копии?
AОна слишком медленная
BВложенные объекты остаются общими, и мутация одной копии задевает другую
CОна копирует слишком много
DОна не работает в Python
3. Какой инструмент Python реализует глубокое клонирование?
Acopy.copy
Bcopy.deepcopy
Cclone()
Dpickle.dump
Поддержать проект