Расскажите о паттернах проектирования Singleton, Factory, Decorator и их применении
Что проверяют
Отличаете ли вы задачу, которую решает паттерн, от его реализации. На фронтенде все три паттерна вы уже использовали, не называя по имени: модуль конфигурации, фабрика обработчиков, обёртка над fetch. Интервьюер смотрит, приведёте ли вы примеры из своего кода вместо пересказа учебника, и понимаете ли цену каждого решения.
Как отвечать
Коротко определение, потом реальное место в проекте, потом ограничение.
- Singleton: один экземпляр на всё приложение и общая точка доступа к нему. В JavaScript модуль сам по себе синглтон:
export const api = createApi()выполнится один раз, и все импорты получат один объект. Отдельный класс с полемinstanceнужен редко. - Factory: функция или метод, который решает, объект какого типа создать, и прячет
newот вызывающего кода. Типичный фронтендовый случай: разбор входящего события в конкретный объект по полюtype. - Decorator: обёртка, добавляющая поведение при сохранении интерфейса. Обёртка над
fetchс повторами и логом, компонент высшего порядка в React, middleware в Redux.
const withRetry = (fetcher, tries = 3) => async (url) => {
for (let i = 0; i < tries; i++) {
try { return await fetcher(url); } catch (e) { if (i === tries - 1) throw e; }
}
};Сильный ответ заканчивается тем, когда паттерн вреден: синглтон это глобальное состояние, из-за которого тесты начинают влиять друг на друга.
Где спотыкаются
Путают Decorator из книги с декораторами TypeScript. Синтаксис вида @Component это метапрограммирование поверх класса, а паттерн это композиция объектов, общее у них только название.
Второе: описывают Singleton классом с проверкой в конструкторе и не замечают, что в модульной системе он избыточен, а при серверном рендере ещё и опасен: один экземпляр на процесс означает, что данные одного пользователя достанутся другому.
Третье: называют фабрикой любую функцию, возвращающую объект. Фабрика нужна там, где выбор конкретного типа зависит от входных данных, иначе это обычный конструктор с лишним слоем.