Ответ
В моей практике разработки на Node.js я избегаю дублирования кода в следующих случаях:
1. Бизнес-логика и валидация
// Плохо: дублирование валидации email
function registerUser(userData) {
if (!userData.email.includes('@')) {
throw new Error('Invalid email');
}
// регистрация
}
function updateUser(userData) {
if (!userData.email.includes('@')) {
throw new Error('Invalid email');
}
// обновление
}
// Хорошо: единая функция валидации
function validateEmail(email) {
const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
return emailRegex.test(email);
}
2. Конфигурация и подключения В Node.js проектах я выношу конфигурацию базы данных, настройки логгера или клиентов внешних API в отдельные модули:
// database.js
const knex = require('knex');
const dbConfig = {
client: 'pg',
connection: process.env.DATABASE_URL
};
module.exports = knex(dbConfig);
// Теперь используется во всех модулях
const db = require('./database');
3. Middleware в Express.js
// Дублирование проверки аутентификации
app.get('/api/profile', (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
// логика
});
app.get('/api/settings', (req, res) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
// логика
});
// Лучше: middleware
const authMiddleware = (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
};
app.get('/api/profile', authMiddleware, profileHandler);
app.get('/api/settings', authMiddleware, settingsHandler);
Когда дублирование может быть оправдано:
- Простые утилитарные функции в разных контекстах
- Когда абстракция усложнит код больше, чем дублирование
- В прототипах или временных решениях
Ответ 18+ 🔞
Э, слушай, а вот это реально важная тема, про дублирование кода. Я тебе как старый пердун, который на Node.js уже столько говна написал, что можно было бы удобрить все поля Подмосковья, скажу: бойся дублирования как огня, но и не делай из этого культа, а то сам себе выстрелишь в ногу.
Вот смотри, есть места, где дублировать — это просто пиздец какой-то грех, ёпта.
1. Вся эта ваша бизнес-логика и проверки
Представь, ты пишешь функцию для регистрации юзера и для его обновления. И в обеих тупо копипастишь проверку мыла. Ну это же манда с ушами получается! Завтра заказчик придет и скажет: «А давайте мыло теперь проверять по новой схеме, там три собаки должно быть». И ты пойдешь по всему проекту, как угорелый, искать все эти if (!userData.email.includes('@')). Овердохуища работы, а главное — накосячить проще простого. Один раз забудешь — и всё, приехали. Выноси в отдельную функцию validateEmail и спи спокойно, блядь.
2. Конфиги и подключения к базе
Это вообще классика, ядрёна вошь. Ты в каждом файле, где нужно с базой работать, начинаешь импортировать knex и настраивать его заново? Да ты что, с ума сошел? Это же чистой воды распиздяйство. Создал один файлик database.js, настроил там соединение один раз и на всю жизнь, и потом отовсюду его импортируешь. И если что-то поменяется (а оно всегда меняется), ты правишь в одном месте, а не бегаешь по всему проекту, как сука обезумевшая.
// database.js — сделал один раз и забыл
const knex = require('knex');
const dbConfig = { client: 'pg', connection: process.env.DATABASE_URL };
module.exports = knex(dbConfig);
3. Middleware в Express — это святое!
Вот это, блядь, реально больное место. Видел я такие проекты, где в каждом роуте по десять строк одинаковой проверки на авторизацию торчит. Представь: у тебя 50 защищенных эндпоинтов. И в каждом if (!req.headers.authorization). А потом тебе говорят: «Добавь еще проверку роли». И что, ты в 50 мест полезешь? Да похуй, я лучше повешусь. Сделал один мидлвар authMiddleware, кинул его перед хендлерами — и вся магия. Изменил логику в одном месте — она применилась везде. Красота, ёперный театр!
// Сделал один раз — и везде работает. Умно, да?
const authMiddleware = (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
};
app.get('/api/profile', authMiddleware, profileHandler);
НО! Не надо фанатеть, чувак. Иногда дублирование — это не грех, а мудрое решение.
- Простые утилитки в разных модулях. Если в одном файле нужна функция
formatDate, а в другом — точно такая же, но они друг про друга не знают и никогда не будут связаны... Ну, скопируй её, и хуй с горы. Выносить её в общую либу и тащить зависимость — это иногда оверкилл, честно. - Когда абстракция начинает мозг выносить. Бывает, пытаешься сделать одну супер-универсальную функцию, а она обрастает условиями, флагами и становится неподъёмной хитрой жопой. В итоге её сложнее читать, чем два простых дубликата. Вот тут лучше оставить как есть. Простота важнее.
- В прототипах или временных костылях. Ну скинул ты быстренько PoC, там код повторяется. Да и ладно, терпения ноль ебать на этапе прототипа. Главное — потом, когда это пойдет в продакшн, не забыть причесать. А то так и живут с этим.
Короче, правило простое: думай головой, а не жопой. Если видишь одинаковую логику в двух местах — спроси себя: «А если её поменять, мне везде придется бегать?». Если да — выноси. Если нет — можешь оставить. Главное — не превращай код в ёбушки-воробушки, где всё связано так, что чихнешь — всё развалится.