Как работает паттерн Prototype в Java?

«Как работает паттерн Prototype в Java?» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Prototype — это порождающий паттерн, который позволяет создавать новые объекты путем клонирования существующего объекта-прототипа, вместо создания через конструктор.

Зачем это нужно?

  • Когда создание объекта сложное или ресурсоемкое (например, требует запросов к БД).
  • Когда система должна быть независима от способа создания и композиции объектов.
  • Когда нужно создавать объекты, чьи классы определяются во время выполнения.

Реализация в Java: Базовый класс (или интерфейс) реализует метод clone().

// 1. Интерфейс Prototype
interface Prototype extends Cloneable {
    Prototype clone() throws CloneNotSupportedException;
}

// 2. Конкретный класс, реализующий прототип
class ConcretePrototype implements Prototype {
    private String field;

    public ConcretePrototype(String field) {
        this.field = field;
        // Имитация ресурсоемкой инициализации
        System.out.println("Выполнена сложная инициализация...");
    }

    public void setField(String field) { this.field = field; }
    public String getField() { return field; }

    @Override
    public Prototype clone() throws CloneNotSupportedException {
        // Поверхностное клонирование (shallow copy) средствами Java
        return (ConcretePrototype) super.clone();
        // Для глубокого копирования (deep copy) нужна дополнительная логика.
    }
}

// 3. Использование
public class Client {
    public static void main(String[] args) throws Exception {
        // Создаем дорогой оригинальный объект один раз
        ConcretePrototype original = new ConcretePrototype("Original Value");

        // Создаем новые объекты путем клонирования (быстро и без повторной инициализации)
        ConcretePrototype copy1 = (ConcretePrototype) original.clone();
        copy1.setField("Modified in Copy1");

        ConcretePrototype copy2 = (ConcretePrototype) original.clone();

        System.out.println(original.getField()); // Original Value
        System.out.println(copy1.getField());    // Modified in Copy1
        System.out.println(copy2.getField());    // Original Value
    }
}

Ключевой момент: Паттерн Prototype в Java не имеет прямого отношения к наследованию (extends) или полю prototype из JavaScript. Его суть — клонирование существующих экземпляров.