Что это такое
Паттерн Factory Method прячет создание объекта за функцией. Вызывающий код говорит, что ему нужно, — а фабрика решает, какой конкретный класс создать, и возвращает его как интерфейс.
Вызывающий код никогда не обращается к конкретным классам, поэтому новые виды можно добавлять, не меняя ни строчки вызывающего кода. В TypeScript это просто функция createSomething(), тип возвращаемого значения которой — интерфейс.
Пример: фабрика хранилищ
createStorage("disk") и createStorage("memory") возвращают разные конкретные классы за одним и тем же интерфейсом OrderStorage — вызывающий код не видит разницы, и она ему не нужна.
Фабрика выбирает класс
switch по видам живёт в одном месте — в фабрике. Остальная программа знает только интерфейс, поэтому цикл вызывает store.save(), даже не спрашивая, что именно он получил.
Вывод: программа на TypeScript и захваченный вывод
interface OrderStorage {
save(data: string): string
}
class DiskStore implements OrderStorage {
save(data: string): string {
return "диск: записан " + data
}
}
class MemoryStore implements OrderStorage {
save(data: string): string {
return "память: сохранён " + data
}
}
// Фабрика решает, какой конкретный класс создать.
function createStorage(kind: string): OrderStorage {
switch (kind) {
case "memory":
return new MemoryStore()
default:
return new DiskStore()
}
}
for (const kind of ["disk", "memory"]) {
const store = createStorage(kind)
console.log(store.save("заказ #1042"))
}
Когда это использовать
Используйте, когда конкретный класс зависит от того, что известно только во время выполнения, — значения конфигурации, выбора пользователя, окружения, — или когда вы хотите держать логику создания ровно в одном месте.
Не используйте, когда реализация одна и второй не предвидится. Для const store = new DiskStore() фабрика не нужна.
Плюсы и минусы
Плюсы: логика создания в одном месте; вызывающий код зависит только от интерфейса; добавление нового вида затрагивает только фабрику.
Минусы: ещё один слой, который нужно прочитать; при единственной реализации это чистая формальность.