Как правила линтинга влияют на архитектуру

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В eslint есть одно простое, но мощное правило, которое поможет вам в поддержании архитектуры приложения.

import/no-restricted-paths позволяет указать зону, по которой запрещено импортировать определенные пути:

"zones": [{
  "target": ["./moduleA"],
  "from": ["./moduleB"],
  "message": 'Модуль A не может импортировать модуль B',
}]

Импорт модуля B в модуль A вызовет ошибку в IDE:

ESLint: Unexpected path "/moduleB" imported in restricted zone. 
Модуль A не может импортировать модуль B(import/no-restricted-paths)

Импорты — это отражение связей между модулями в коде, а связи в хорошо спроектированной архитектуре должны контролироваться и быть прозрачными. 

Далее рассмотрим, как одна простая настройка eslint-правила поможет при проектировании, разработке или рефакторинге сложных систем.

Влияние импортов на архитектуру

В любой архитектуре есть модули, которые взаимодействуют друг с другом.

Каждый такой модуль строится в первую очередь на принципе единственной ответственности (The Single Responsibility Principle или SRP) — “модуль должен иметь одну и только одну причину для изменения”. 

Правильные связи между этими модулями —  один из важных аспектов построения масштабируемой архитектуры и развития проекта. Когда мы импортируем один модуль в другой, мы создаем между ними связь, следовательно, импорт = связь.

Как часто вы сталкиваетесь с архитектурными спорами в проекте?
Бывает ли, что неудачные архитектурные решения пролезают в проект даже после код-ревью? Знаете ли вы, насколько связаны модули в вашем приложении?

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

В целом, кажется, всё сводится к человеческому фактору. А человеческий фактор нужно автоматизировать.

Пример использования

Рассмотрим следующий пример. Стрелками на картинке обозначены импорты/связи между модулями

Пример некорректного использования импортов
Пример некорректного использования импортов

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

Так как же это автоматизировать?

rules: {
  'import/no-restricted-paths': ['error', {
    "basePath": rootPath,
    "zones": [{
      "target": ["./lib/ui-kit/*"],
      "from": ["./backend/rest-api"],
      "message": 'Пакет ui-kit не может содержать импорт из rest-api',
    }],
  }],
}

Не правда ли, очень дешево написать пару строчек конфига и решить потенциальные проблемы архитектуры?

Заключение

Проектирование модуля, в котором соблюдается Single Responsibility Principle упрощает дальнейшие изменения и поддержку, так как это освобождает команду от распутывания сложных взаимосвязей между различными сущностями. Также несвязанные модули снижают риск возникновения проблем в других местах при изменениях.

Есть еще много способов снизить связность — микросервисы, монорепа, отдельные пакеты.  Но даже там могут возникнуть ошибки, если один пакет будет использовать другой. 

Итого  import/no-restricted-paths:

  • Помогает контролировать связанность модулей.

  • Упрощает рефакторинг модуля.
    Можно зафиксировать связи модуля и начать его доработку.

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

Теперь с помощью простого правила eslint можно быть уверенным, что принцип SRP соблюдается в полной мере. Нам это пригодилось при переходе  от монолита к монорепе, помогло зафиксировать связи между сущностями и начать распил монолита.

А какие неожиданные решения архитектурных проблем встречали вы?

Источник: https://habr.com/ru/company/okko/blog/716042/


Интересные статьи

Интересные статьи

Недавно Ася Казанцева выступила с лекцией «Не забудьте побездельничать». Привожу 10-минутный конспект со ссылками на оригинальные исследования, чтобы можно было принять решение, стоит ли тратить 2...
В предыдущей статье мы анонсировали Dart Code Metrics — инструмент статического анализа кода. Сегодня я расскажу про новые возможности, которые появились в Dart Code Metrics с выхо...
Контент должен быть индексируемым в событии загрузки, чтобы контент JavaScript имел смысл для поисковых систем. Контент, зависящий от пользовательских событий, не индексируется. Для сайтов JS требуетс...
Выбор правильной архитектуры для вашего веб-продукта — это важнейший вопрос, который необходимо решить, продумывая его разработку. Прежде всего, он должен быть масштабиру...
Некоторое время назад мне довелось пройти больше десятка собеседований на позицию php-программиста (битрикс). К удивлению, требования в различных организациях отличаются совсем незначительно и...