Если вы еще не видели, поищите мой пост о шаблонах проектирования в целом. Вы можете бесплатно найти список объясненных шаблонов дизайна в одном месте! 💰 Также прочтите статью о Строителе 👨🏭 или воспользуйтесь фабричным методом с Одиночным паттерном.
Что это?
Также известен как «именованный конструктор». Почему? Потому что, в конце концов, это более чистый способ вызова самого конструктора. Могу я просто пойти и использовать конструктор? Конечно вы можете! Шаблоны проектирования должны были помочь разработчикам решать проблемы, но если вы видите возможность создать новый или лучший подход - дерзайте!
Пример
Вы можете найти примеры использования шаблонов проектирования на современных языках. Давайте посмотрим на класс 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.)); }
Вам понравилась эта запись? Узнай больше в моем профиле 👨 И не забывай хлопать 👏