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 копии. - Полезен, когда настройка объекта дороже его копирования.