Skip to content

Принцип устойчивых зависимостей (SDP)

ID: sdp_violation | Степень критичности: Средняя (по умолчанию)

Принцип устойчивых зависимостей (Stable Dependencies Principle) гласит: «зависимости между пакетами должны быть направлены в сторону устойчивости». Другими словами, устойчивые (трудноизменяемые) модули не должны зависеть от неустойчивых (легкоизменяемых) модулей.

Устойчивость в данном контексте измеряется тем, сколько других модулей зависят от данного модуля (Fan-in) по сравнению с тем, от скольких модулей зависит он сам (Fan-out).

Почему это «запах»

Если устойчивый модуль — тот, на который полагаются многие другие компоненты — зависит от неустойчивого модуля, его становится сложно изменять. Любое изменение в неустойчивой зависимости может нарушить работу устойчивого модуля, что затем вызовет цепную реакцию у всех его потребителей. Это фактически «замораживает» неустойчивый модуль или делает всю систему хрупкой.

Примеры

Плохо

Сущность ядра предметной области (устойчивая), зависящая от конкретной реализации базы данных или часто меняющегося компонента пользовательского интерфейса (неустойчивая).

typescript
// domain/user.ts (устойчивый, многие вещи зависят от User)
import { UserPreferencesUI } from '../ui/user-prefs'; // неустойчивая зависимость

export class User {
  updateSettings(prefs: UserPreferencesUI) {
    // ...
  }
}

Хорошо

Устойчивый модуль зависит от абстракции (например, интерфейса), которая меняется редко.

typescript
// domain/user.ts
export interface UserSettings {
  theme: string;
  notifications: boolean;
}

export class User {
  updateSettings(settings: UserSettings) {
    // ...
  }
}

Конфигурация

yaml
rules:
  sdp_violation:
    severity: medium
    min_fan_total: 5
    instability_diff: 0.3

ESLint правило

Этот детектор доступен как правило ESLint для получения обратной связи в реальном времени.

javascript
// eslint.config.js
export default [
  {
    rules: {
      '@archlinter/no-sdp-violations': 'warn',
    },
  },
];

Смотрите Интеграция с ESLint для инструкций по настройке.

Как исправить

Убедитесь, что ваши основные, устойчивые модули не зависят от изменчивых модулей. Используйте интерфейсы или абстрактные классы для их разделения (decoupling).

Параметры по умолчанию

  • instability_diff: 0.3 - минимальная разница в нестабильности между модулями для обнаружения нарушения
  • min_fan_total: 5 - минимальное общее количество зависимостей (fan-in + fan-out) для анализа

Released under the MIT License.