Если вы еще не видели, поищите мой пост о шаблонах проектирования в целом. Вы можете бесплатно найти список объясненных шаблонов дизайна в одном месте! 💰 Также прочтите статью о Строителе 👨‍🏭 или воспользуйтесь фабричным методом с Одиночным паттерном.

Что это?

Также известен как «именованный конструктор». Почему? Потому что, в конце концов, это более чистый способ вызова самого конструктора. Могу я просто пойти и использовать конструктор? Конечно вы можете! Шаблоны проектирования должны были помочь разработчикам решать проблемы, но если вы видите возможность создать новый или лучший подход - дерзайте!

Пример

Вы можете найти примеры использования шаблонов проектирования на современных языках. Давайте посмотрим на класс Integer старой доброй Java (эй… это все еще современный язык 😉). Это класс-оболочка для примитивного типа int, который имеет два очень полезных фабричных метода - value of - широко используемых в программировании на Java.

Integer.valueOf("44");
Integer.valueOf(44);

За и против

В чем преимущество такого подхода, если можно просто использовать конструктор? Я могу вспомнить несколько:

  • Мы можем заменить тело этого метода, не нарушая существующий код. Если вы посмотрите на тело Integer.valueOf (int), вы увидите улучшения производительности с использованием кешированных значений. Эти улучшения могут быть изменены в каждой версии языка Java, и эти изменения будут полностью прозрачными для нас, программистов, и наша программа останется неизменной, но производительность нашего приложения вырастет бесплатно 📈.
new Integer(44) == new Integer(44) // false
Integer.valueOf(44) == Integer.valueOf(44) // true - value cached
  • ✌️ Удобное именование. Я не знаю вашего мнения (поделитесь им в комментарии ниже 👇), но оставляю на ваше усмотрение, какой из следующих примеров более читабелен.
Executors.newSingleThreadExecutor();
//or
new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
  • 🤟 Не ограничивается классом - может быть в отдельном файле. При желании вы можете реализовать расширенные конструкторы. Но размер файла класса взрывается 🐡. С помощью фабричных методов вы можете переместить их в другое место (см. Executors.java).

Вывод

Лично мне нравится шаблон фабричного метода. Он становится очень мощным в сочетании с паттерном «Адаптер». Я злоупотребляю им при сопоставлении одного объекта с другим. Этот метод адаптации становится моим единственным источником истины. Взгляни:

// Server data
class RemoteOperation {
    public String type;
    public Integer price;
}
// Application data
class Operation {
    public Type type;
    public String price;

    public Operation(Type type, String price) {
        this.type = type;
        this.price = price;
    }

    public static Operation from(RemoteOperation operation) {
        return new Operation(
                Type.from(operation.type),
                String.format("%.2f", operation.price / 100.));
    }
}

enum Type {
    CASH, CREDIT_CARD, UNKNOWN;

    public static Type from(String value) {
        for (Type t : values()) {
            if (t.name().equals(value)) {
                return t;
            }
        }
        return Type.UNKNOWN; // if null or not found
    }
}

Истинная ценность видна при рефакторинге. Допустим, теперь сервер возвращает дополнительную информацию о валюте. Единственное место, где нам нужно изменить нашу программу, - это заводской метод, а остальная часть программы остается нетронутой 👌.

class RemoteOperation {
    public String type;
    public Integer price;
    public String currency;
}
…
public static Operation from(RemoteOperation operation) {
    return new Operation(
            Type.from(operation.type),
            String.format("%s %.2f", operation.currency, operation.price / 100.));
}

Вам понравилась эта запись? Узнай больше в моем профиле 👨 И не забывай хлопать 👏