JavaRush /Курсы /Claude code /Dependency map и карта модулей проекта

Dependency map и карта модулей проекта

Claude code
7 уровень , 3 лекция
Открыта

1. Папки показывают «что есть», а не «как связано»

Дерево папок orders/, payments/, support/, dashboard/ создаёт иллюзию порядка. Но папки — это адреса. Они не говорят, кто кого вызывает.

Смотрите на проект в двух срезах. Внешний: какие библиотеки и фреймворки, каких версий, что притянулось транзитивно. Внутренний: какие модули Commerce OS знают друг о друге, куда идут стрелки, где связанность уже пахнет спагетти.

Карта того, что ищем:

Срез Что ищем Где ищем Зачем
Внешние зависимости библиотеки, фреймворки, версии
build.gradle
,
package.json
,
lockfile
понять стек и реальные версии
Внутренние зависимости связи между модулями импорты, вызовы сервисов, структура пакетов понять влияние изменений
Обратные зависимости кто использует модуль или файл поиск по ссылкам,
grep
,
LSP
найти опасные центральные точки
Архитектурные нарушения циклы и нарушения слоёв карта модулей, импорты, references заранее увидеть зоны риска

Папки — это знание адресов. Зависимости — знание дорожного движения. Только второе даёт писать task spec безопасно, не снося полмагазина одной правкой.

2. Внешние зависимости: манифест врёт, lockfile — нет

Начинайте с внешних: они лежат в конфигурации открыто. Но манифест показывает, что проект хочет использовать, а не что реально установлено.

На фронтенде:

{
  "dependencies": {
    "next": "16.2.0",
    "react": "19.2.0"
  }
}

Это заявка, а не истина. Реальные версии живут в lockfile. Lockfile — источник правды по версиям и дереву зависимостей. Не package.json, не память Claude, не ощущение «тут вроде современный фронтенд».

На backend в Java первый источник — build.gradle:

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.postgresql:postgresql")
    testImplementation("org.springframework.boot:spring-boot-starter-test")
}

Он даёт прямые зависимости. Полную картину перед оценкой риска обновлений даёт дерево:

./gradlew dependencies --configuration runtimeClasspath > deps-backend.txt
# сохраняем дерево backend-зависимостей в файл

npm ls --all > deps-frontend.txt
# сохраняем дерево frontend-зависимостей в файл

Вы разворачиваете дерево, чтобы увидеть не только прямые зависимости, но и транзитивные — те, что притянула за собой другая библиотека.

Просите Claude не «какие тут библиотеки?», а так:

Покажи внешние зависимости проекта в двух частях:
1) прямые зависимости из конфигурации,
2) реально установленные версии по lockfile или дереву зависимостей.
Отдельно отметь backend и frontend.
Для каждого важного утверждения укажи файл или команду-источник.

Здесь работает правило из прошлой лекции: если Claude пишет «проект использует такую-то библиотеку» без источника — это гипотеза, не знание. Проверяйте манифест, lockfile, вывод команды.

3. Внутренние зависимости: куда смотрят стрелки

Внутренние зависимости — не список библиотек, а реальные связи бизнес-логики. Учебный фрагмент карты:

orders    ──► catalog
orders    ──► payments
support   ──► customers
support   ──► ai-assist
dashboard ──► orders
dashboard ──► support

Это не полный граф, а фрагмент. Стрелка — направление зависимости. orders знает о payments. Обратное — не всегда желательно.

В коде это выглядит обыденно:

package com.commerceos.orders;

import com.commerceos.catalog.InventoryService;
import com.commerceos.payments.PaymentService;

public class OrderService {
    private final InventoryService inventoryService;
    private final PaymentService paymentService;
}

OrderService зависит от каталога и платежей — это кусочек карты модулей. На этапе discovery задача — увидеть связь, не оценивать.

Просите карту прямо:

Построй карту внутренних зависимостей проекта.
Для каждого верхнеуровневого модуля покажи:
- от каких внутренних модулей он зависит,
- какие сервисы или классы это подтверждают,
- есть ли подозрительные прямые связи между слоями.
Не предлагай рефакторинг. Сначала только карта и evidence.

Идеальный граф вселенной не нужен — нужен рабочий уровень точности. Знаете, что dashboard тянет orders и support, а supportcustomers и ai-assist, — этого достаточно, чтобы понимать зоны поражения при изменениях.

Есть LSP или поиск references — ускорят задачу. Но не превращайте это в экспедицию по настройке инструментов: на discovery хватает чтения кода, импортов и обычного поиска.

4. Обратные зависимости: кто упадёт, если тронуть

«От чего зависит модуль» — половина картины. Вторая половина — кто зависит от него. Она показывает, почему некоторые файлы не трогают в пятницу вечером перед релизом.

Файл RefundPolicy.java сам по себе короткий. Но если на него ссылаются orders, payments, support и admin — это центральная точка риска. Один автомат в щитке, от которого зависит полквартиры.

Найти просто:

grep -R "RefundPolicy" backend/src backend/test
# ищем, где в проекте упоминается RefundPolicy

Много совпадений по разным модулям — сигнал: правка логики возвратов ударит сразу по нескольким частям. Отметьте такой файл в CODEBASE_INVENTORY.md как рискованный центральный файл.

Различайте два вопроса:

Вопрос Что он означает
От чего зависит payments? что самому модулю нужно для работы
Кто зависит от payments? кого этот модуль может зацепить при изменении

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

Claude и здесь работает предметно:

Для модуля payments найди:
- какие внутренние файлы и сервисы используются чаще всего,
- на какие классы есть много ссылок из других модулей,
- какие файлы выглядят как центральные точки риска.
Подтверждай выводы ссылками на импорты, references или результаты поиска.

Математической идеальности не ждите. Нужен инженерный результат: места, где маленькое изменение даёт большой радиус поражения. Это кандидаты в секцию high-risk вашего inventory.

5. Layer violation и циклы: заметить, не лечить

Когда карта вырисовывается, всплывают два неприятных сюрприза: нарушение слоёв и циклические зависимости. Не катастрофа прямо сейчас, но предупреждение: правьте здесь аккуратно.

layer violation — когда нижний, более технический слой знает о верхнем, бизнесовом. Платежи тащат в себя логику заказов:

package com.commerceos.payments;

import com.commerceos.orders.OrderService; // тревожный сигнал

public class PaymentAuditService {
    private final OrderService orderService;
}

Сам импорт ещё не доказывает катастрофу — возможно, у команды была причина. Discovery нужен, чтобы такие места замечать, а не бежать переписывать. Вы фиксируете доказательства, не рефакторите.

Цикл хуже: два модуля тянут друг друга по кругу.

orders   ──► payments
payments ──► orders

Круг означает, что модули перестают нормально отделяться. Правка в одном тащит второй. Тестировать, переиспользовать, объяснять новичку — всё сложнее.

Дисциплинарное правило: не лечите цикл в той же сессии, где его нашли. Задача на этом этапе — discovery: записать, где найден цикл, какими файлами подтверждается, насколько вы уверены. Хорошая запись в черновике:

Возможен цикл между orders и payments: найден импорт PaymentService в OrderService и ссылка на OrderService в payments. Нужно дополнительно проверить, это реальная бизнес-зависимость или локальный обходной путь.

В такой формулировке есть evidence и нет паники. «Архитектура ужасная, надо всё срочно переделать» — это эмоции, а не analysis.

6. Dependency map в CODEBASE_INVENTORY.md

Превратите находки в артефакт. Всё про зависимости кладите в тот же CODEBASE_INVENTORY.md, а не в отдельные файлы: на первом проходе статическая карта проекта удобнее в одном месте.

Рядом с рискованным выводом оставляйте короткую опору на источник: import, reference, test или команду поиска. Тащить весь лог поиска не нужно.

Фрагмент dependency-секции:

## Карта зависимостей

### Внешние зависимости
- Backend: Gradle, Spring Boot 4.0.6, PostgreSQL driver
- Frontend: Next.js 16.2, React 19.2
- Source of truth: `build.gradle`, `package.json`, lockfiles

### Направление внутреннего модуля
- `orders` -> `catalog`, `payments` (imports внутри `orders/`)
- `support` -> `customers`, `ai-assist` (imports внутри `support/`)
- `dashboard` -> `orders`, `support` (references из `dashboard/`)

### Рискованные центральные файлы
- `payments/RefundPolicy.java` — используется в нескольких модулях, менять осторожно (`grep -R "RefundPolicy" backend/src backend/test`)
- `orders/OrderStatus.java` — много ссылок из разных частей проекта (`git grep "OrderStatus"`)

### Подозрительные точки
- возможная циклическая связь `orders` <-> `payments` (`orders/OrderService` импортирует `PaymentService`; `payments/PaymentAuditService` импортирует `OrderService`) [нужно подтвердить]
- подозрение на нарушение слоя в `payments/...` через прямой импорт `orders` (`payments/PaymentAuditService`)

Помечайте, что подтверждено, а что только вероятно: [подтверждено], [нужно проверить], [не проверено]. Честный inventory полезнее красивого. И не рисуйте огромный граф — храните компактные выводы: кто с кем связан, где центральные узлы, какие файлы опасны для правок.

Так CODEBASE_INVENTORY.md перестаёт быть аккуратным markdown и становится рабочей картой проекта. Вернётесь к Commerce OS через неделю разбирать задачу по возвратам — и не придётся заново вспоминать, почему RefundPolicy хочется трогать в перчатках.

1
Задача
Claude code, 7 уровень, 3 лекция
Недоступна
Расхождение карты модулей и сборки: недостающая зависимость
Расхождение карты модулей и сборки: недостающая зависимость
1
Задача
Claude code, 7 уровень, 3 лекция
Недоступна
Применение reverse dependency mapping к risky file
Применение reverse dependency mapping к risky file
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ