До 30 ноября

Скидки до 81 000 руб и вторая профессия в подарок!

Главная | Все статьи | Код

Совершенный код: интерфейсы модулей

Время чтения статьи ~2 минуты 90
Совершенный код: интерфейсы модулей главное изображение

В некоторых языках, таких как Python или JavaScript, переменные или константы, определенные на уровне модуля, могут быть импортированы в других частях программы. С одной стороны, это открывает больше возможностей по сравнению с языками, где любые данные должны находиться внутри функций, классов и так далее. С другой стороны, становится гораздо легче писать плохо поддерживаемый код.

Представим, что мы пишем веб-сервис, который умеет конвертировать валюты. В этом конвертере присутствует описание того, какая валюта в какую может конвертироваться, и по какому курсу:

// currency.js
export const rates = {
  eur: {
    usd: 1.3
    rub: 80.99
  },
  usd: {
    eur: 1.4
  },
  rub: {
    usd: 72.10
  },
};

Остальные части программы используют эту информацию для своих вычислений и проверок:

import rates from './currency.js';

// Обработчик, который возвращает страницу с указанием рейта
// по конкретной паре валют
const getRate = (req, res) => {
  // Параметры из адреса запрошенной страницы
  const { from, to } = req.query;
  const rate = rates[from][to];

  // Тут формируется HTML и отправляется пользователю в браузер
  res.render('rate.pug', { rate });
}

Код получился простой, но ненадежный. Если пользователь выполнит запрос на рейт валют, которых нет в системе, возникнет ошибка доступа к объекту:

// Boom! rates['gdr'] === undefined
const rate = rates['gbr']['usd'];

Даже если первая валюта есть, то при отсутствии второй в константе rate окажется undefined, что может быть неверным (зависит от приложения).

Перепишем код и избавимся от ошибки:

import rates from './currency.js';

const getRate = (req, res) => {
  const { from, to } = req.query;
  const rate = rates[from] ? rates[from][to] : null;
  // Версия с lodash
  // const rate = _.get(rates, [from, to], null);

  res.render('rate.pug', { rate });
}

Ошибка больше не возникнет, но решение все еще плохое. Работа с rates наверняка не ограничится одним обработчиком. С ростом приложения рейты начнут использоваться повсеместно, а это значит, что и обработку ошибок придется делать в каждом месте. Кроме того, любое изменение структуры данных также потребует переписывания всех мест, где они используются.

Подписывайтесь на канал Кирилла Мокевнина в Telegram — чтобы узнать больше о программировании и профессиональном пути разработчика

Указанные проблемы типичны для всех ситуаций, когда работа с данными идет напрямую без создания хотя бы минимальной абстракции (функций) для доступов к данным. Решается все очень просто, нужно лишь добавить функцию в модуль currency.js.

// currency.js
// Данные не экспортируются наружу
// к ним нельзя получить прямой доступ
const rates = {
  eur: {
    usd: 1.3
    rub: 80.99
  },
  usd: {
    eur: 1.4
  },
  rub: {
    usd: 72.10
  },
};

export const getRate = (from, to) => {
  if (!_.has(rates, [from, to])) {
    throw new Error(`Unknown rate: from '${from}', to '${to}'.`);
  }
  return rates[from][to];
}
Аватар пользователя Kirill Mokevnin
Kirill Mokevnin 16 марта 2020
90
Рекомендуемые программы
профессия
Осваивайте разработку веб-страниц, оживляйте дизайн макетов, публикуйте сайты и приложения. Отслеживайте ошибки в интерфейсе и устраняйте их
10 месяцев
с нуля
Старт 28 ноября
профессия
Обучитесь разработке бэкенда сайтов и веб-приложений — серверной части, которая отвечает за логику и базы данных
10 месяцев
с нуля
Старт 28 ноября
профессия
Выполняйте ручное тестирование веб-приложений, находите ошибки в продукте. Узнайте все о тест-дизайне.
4 месяца
с нуля
Старт 28 ноября
профессия
Научитесь разработке веб-приложений, сайтов и программного обеспечения на языке Java, программируйте и используйте структуры данных
10 месяцев
с нуля
Старт 28 ноября
профессия
новый
Собирайте, анализируйте и интерпретируйте данные, улучшайте бизнес-процессы и продукт компании. Обучитесь работе с библиотеками Python
9 месяцев
с нуля
Старт 28 ноября
профессия
Занимайтесь созданием сайтов, веб-приложений, сервисов и их интеграцией с внутренними бизнес-системами на бекенд-языке PHP
10 месяцев
с нуля
Старт 28 ноября
профессия
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 28 ноября
профессия
Обучитесь разработке визуальной части сайта — фронтенда, а также реализации серверной — бэкенда. Освойте HTML, CSS, JavaScript
16 месяцев
с нуля
Старт 28 ноября
профессия
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 28 ноября
профессия
новый
Организовывайте процесс автоматизации тестирования на проекте, обучитесь языку программирования JavaScript, начните управлять процессом тестирования
8 месяцев
c опытом
Старт 28 ноября