Найти в Дзене

🏗 Паттерн “Строитель”: когда он нужен, а когда — просто усложняет код

🏗 Паттерн “Строитель”: когда он нужен, а когда — просто усложняет код Многие начинают применять Builder просто потому, что «так красиво» или «видел в чьем-то коде». Давай разберёмся, где он реально решает проблему, а где — избыточен. Что такое Builder? Это паттерн, который помогает создавать сложные объекты пошагово, скрывая детали и делая процесс конструирования более контролируемым. Классика: объект с кучей необязательных полей и сложной логикой инициализации. Когда Builder оправдан? ✅ У объекта много параметров Особенно если часть из них необязательная, а комбинации параметров — разные. const user = UserBuilder .withName("Dmitry") .withEmail("dmitry@example.com") .asAdmin() .build() Читабельно, декларативно, структурировано. Цена использования Builder'а 1. Больше кода Придётся описывать отдельный класс строителя: методы, внутренний state, build(). 2. Ложное ощущение сложности Появление Builder'а может создать иллюзию, что объект сложный, хотя на деле проблема решалась обы

🏗 Паттерн “Строитель”: когда он нужен, а когда — просто усложняет код

Многие начинают применять Builder просто потому, что «так красиво» или «видел в чьем-то коде». Давай разберёмся, где он реально решает проблему, а где — избыточен.

Что такое Builder?

Это паттерн, который помогает создавать сложные объекты пошагово, скрывая детали и делая процесс конструирования более контролируемым.

Классика: объект с кучей необязательных полей и сложной логикой инициализации.

Когда Builder оправдан?

✅ У объекта много параметров

Особенно если часть из них необязательная, а комбинации параметров — разные.

const user = UserBuilder

.withName("Dmitry")

.withEmail("dmitry@example.com")

.asAdmin()

.build()

Читабельно, декларативно, структурировано.

Цена использования Builder'а

1. Больше кода

Придётся описывать отдельный класс строителя: методы, внутренний state, build().

2. Ложное ощущение сложности

Появление Builder'а может создать иллюзию, что объект сложный, хотя на деле проблема решалась обычным объектом или функцией.

3. Избыточность в функциональном стиле

Если объект простой, то Builder только скрывает правду:

// ❌ Overkill

const config = new ConfigBuilder()

.setMode("dark")

.setCaching(false)

.build()

То же самое проще и честнее:

// ✅ Работает так же

const config = { mode: "dark", caching: false }

Функциональная альтернатива Builder'у

Если хочешь декларативность, но без ceremony, используй фабричные функции:

type UserOptions = Partial<{

name: string

email: string

isAdmin: boolean

}>

function createUser(opts: UserOptions = {}) {

return {

name: opts.name ?? "Guest",

email: opts.email ?? null,

isAdmin: opts.isAdmin ?? false

}

}

const user = createUser({ name: "Dmitry", isAdmin: true })

Плюсы: меньше кода, проще тестировать, всё прозрачно.

Когда Builder НЕ нужен?

❌ Объект простой

❌ Нет сложной валидации

❌ Инициализация линейная и очевидная

❌ Можно обойтись обычными аргументами или фабрикой

❌ Builder добавляет больше шума, чем смысла

Когда Builder — прям мастхэв?

✔ Объект реально сложный

✔ Много опциональных параметров

✔ Нужно навязать ограничения

✔ Важна пошаговая сборка

✔ Нужны разные пресеты (разные director'ы)

Вывод

“Строитель” — мощный инструмент, но не магия.

Применяй его там, где объект действительно сложно создать, а не там, где хочется «красивых цепочек методов».

Правило: Начни с простой фабрики. Перейди к Builder'у только когда код станет больно читать и больно расширять.

Сталкивались с ситуациями, когда Builder только всё усложнил? 💬

#architecture #patterns #builder #typescript #bestpractices #frontend