# Prototype and Cloning — Design Patterns

Source: https://www.skillbyai.com/en/design-patterns/c-prototype

> Create new objects by copying a configured one.

## Copying instead of constructing

**Intent:** create new objects by copying an existing, already configured **prototype** rather than building from scratch. It helps when construction is expensive or complex and many objects differ only slightly: document templates, game entities, default request configurations. The key decision is **shallow versus deep copy**: a shallow copy shares nested objects, so mutating one copy can change another. JavaScript is itself prototype-based, and modern runtimes provide `structuredClone()` for deep copies of plain data (it does not copy functions or class prototypes, so check the docs for what it supports). In Python, the `copy` module offers `copy.copy` and `copy.deepcopy`. **Avoid** cloning objects that hold resources such as open connections or file handles.

## Cloning a report template

Python, where the copy module is idiomatic.

```python
import copy
from dataclasses import dataclass, field

@dataclass
class ReportTemplate:
    title: str
    sections: list[str] = field(default_factory=list)
    filters: dict[str, str] = field(default_factory=dict)

monthly_sales = ReportTemplate(
    title="Monthly sales",
    sections=["summary", "by-region", "top-products"],
    filters={"currency": "EUR"},
)

# Deep copy: the new report gets its own lists and dicts
q3_report = copy.deepcopy(monthly_sales)
q3_report.title = "Q3 sales"
q3_report.filters["quarter"] = "Q3"

# A shallow copy would share `filters`, so the edit above
# would also change monthly_sales.filters
shared = copy.copy(monthly_sales)
```

## Spread is shallow

In JavaScript, `{ ...obj }` and `[...arr]` copy only the top level; nested objects are still shared between the original and the copy.

**Quiz:** What is the risk of a shallow copy?

- [ ] It cannot copy strings
- [ ] It deletes the original
- [x] Nested objects are shared, so changing them in one copy affects the other
- [ ] It always throws for nested data

*Answer:* Nested objects are shared, so changing them in one copy affects the other. Only the top level is duplicated.
