alex4answ
@alex4answ

Как бороться с шаблонным кодом, избыточная декомпозиция?

Добрый вечер, одна из главных проблем моих проектов - повторения и шаблонный код, что нарушает DRY, я стремлюсь к максимальной декомпозиции, но на мой взгляд часто это избыточно и усложняет проект.

Например есть middleware Multer (загрузка файлов):
// categoryRouter.js
const fileFilter = (req, file, cb) => {
  const allowedMimeType = ['image/png', 'image/jpeg', 'image/jpg'];
  if (allowedMimeType.includes(file.mimetype) {
    cb(null, true);
  } else {
    cb(new Error('Invalid file type'));
  }
};

const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, path.resolve('public/uploads/categories'));
  },
  filename: (req, file, cb) => {
    cb(null, `${uuidv4()}${path.extname(file.originalname)}`);
  }
});

router.post('/:slug/uploadImage', multer({ storage, fileFilter }).single('image'), (req, res) => {
  // сохранить путь в бд
});


Этот кусок повторяется из модуля в модуль, меняется лишь destination (путь) сохранения и fileFilter (валидатор файла), мне кажется логично декомпозировать этот код примерно так:
fileHelper.js

Проверка на MimeType, генерация уникального имени файла уходят в отдельный модуль-хелпер
// fileHelper.js
exports.isImage = ({ mimetype }) => ['image/png', 'image/jpeg', 'image/jpg'].includes(mimetype);

exports.getUniqueFileName = (originalName) => `${uuidv4()}${path.extname(originalName)}`;


fileFilter

fileFilter уходит в отдельный модуль - utils
// fileFilter.js
module.exports = (fileValidation) => {
  return (req, file, cb) => {
    if (fileValidation(file)) {
      cb(null, true);
    } else {
      cb(new Error('Invalid file type'));
    }
  };
};


Фабрика multer (uploadImage)

storage не вижу смысла выносить отдельно-
module.exports = (destination) => {
  const filter = fileFilter(fileHelper.isImage);
  const storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, destination);
    },
    filename: (req, file, cb) => {
      cb(null, fileHelper.getUniqueFileName(file.originalname));
    }
  });

  return multer({ storage, fileFilter });
};



И в итоге вместо копирование, у нас есть "генератор" middleware:
const uploadImage = require('./multerFactory')('public/uploads/category');

router.post('/:slug/uploadImage', uploadImage.single('image'), (req, res) => {
  // сохранить ссылку на файл в бд
});


1. На сколько такой подход оправдан и необходим?
2. Как обычно поступают в подобных случаях?
3. Не избыточно ли я декомпозировал все? (либо можно еще лучше, как?)

P.S. Не могу найти "боевой", реальный пример полноценного приложения на express / node, отсюда куча "философских" вопросов на который сложно найти однозначный ответ.
  • Вопрос задан
  • 110 просмотров
Решения вопроса 1
bingo347
@bingo347
Crazy on performance...
1. На сколько такой подход оправдан и необходим?
Вполне себе оправдан. Представьте, что через месяц после запуска на Вас сваливается таска "быстро заканчивается место на диске, давайте как-то по другому хранить, и загрузку не забудьте поменять", как будет проще, одно место поправить или везде где накопипастили?

2. Как обычно поступают в подобных случаях?
Если какой-то участок кода повторяется более 1 раза, то выносят его в отдельную функцию. Так что направление Вы выбрали верное.

3. Не избыточно ли я декомпозировал все? (либо можно еще лучше, как?)
Покажите коллеге, сможет ли он без объяснения разобраться, что происходит?
Ну и если пользуетесь VSCode, то вот еще может помочь: https://marketplace.visualstudio.com/items?itemNam...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы