324 lines
11 KiB
Markdown
324 lines
11 KiB
Markdown
|
|
# 📦 Стоит ли выносить Database (Drift + DAO) в отдельный пакет?
|
|||
|
|
|
|||
|
|
## 🤔 Краткий ответ
|
|||
|
|
|
|||
|
|
**Для текущего проекта: НЕТ, выносить не нужно.**
|
|||
|
|
|
|||
|
|
Но давайте разберем, когда это имеет смысл, а когда нет.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ Когда выносить имеет смысл
|
|||
|
|
|
|||
|
|
### 1. Множественное использование в разных проектах
|
|||
|
|
|
|||
|
|
Если database используется в нескольких независимых проектах:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
mnemo_cards_database/ ← Отдельный пакет
|
|||
|
|
├── lib/
|
|||
|
|
│ ├── database.dart
|
|||
|
|
│ ├── tables/
|
|||
|
|
│ └── daos/
|
|||
|
|
└── pubspec.yaml
|
|||
|
|
|
|||
|
|
mnemo_cards_backend/ ← Использует database
|
|||
|
|
└── pubspec.yaml
|
|||
|
|
dependencies:
|
|||
|
|
mnemo_cards_database:
|
|||
|
|
path: ../mnemo_cards_database
|
|||
|
|
|
|||
|
|
mnemo_cards_admin_tool/ ← Тоже использует database
|
|||
|
|
└── pubspec.yaml
|
|||
|
|
dependencies:
|
|||
|
|
mnemo_cards_database:
|
|||
|
|
path: ../mnemo_cards_database
|
|||
|
|
|
|||
|
|
mnemo_cards_analytics/ ← И это тоже
|
|||
|
|
└── pubspec.yaml
|
|||
|
|
dependencies:
|
|||
|
|
mnemo_cards_database:
|
|||
|
|
path: ../mnemo_cards_database
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Плюсы:**
|
|||
|
|
- ✅ Переиспользование в нескольких проектах
|
|||
|
|
- ✅ Централизованное управление схемой БД
|
|||
|
|
- ✅ Общие миграции для всех проектов
|
|||
|
|
- ✅ Избежание дублирования кода
|
|||
|
|
|
|||
|
|
**Когда это нужно:**
|
|||
|
|
- У вас несколько backend сервисов (микросервисы)
|
|||
|
|
- Есть отдельные инструменты (admin panel, analytics, migration tools)
|
|||
|
|
- Разные команды работают с одной БД
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. Публикация как библиотека
|
|||
|
|
|
|||
|
|
Если вы хотите опубликовать database layer как отдельную библиотеку:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
# mnemo_cards_database/pubspec.yaml
|
|||
|
|
name: mnemo_cards_database
|
|||
|
|
version: 1.0.0
|
|||
|
|
publish_to: pub.dev # Публикуется для всех
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Плюсы:**
|
|||
|
|
- ✅ Можно использовать в других проектах
|
|||
|
|
- ✅ Версионирование отдельно от backend
|
|||
|
|
- ✅ Переиспользование в открытых проектах
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. Тестирование изолированно
|
|||
|
|
|
|||
|
|
Если нужно тестировать database layer отдельно:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
mnemo_cards_database/
|
|||
|
|
├── lib/
|
|||
|
|
└── test/
|
|||
|
|
└── database_test.dart # Тесты только для database
|
|||
|
|
|
|||
|
|
mnemo_cards_backend/
|
|||
|
|
└── test/
|
|||
|
|
└── integration_test.dart # Интеграционные тесты
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Плюсы:**
|
|||
|
|
- ✅ Изолированное тестирование database layer
|
|||
|
|
- ✅ Можно тестировать без запуска всего backend
|
|||
|
|
|
|||
|
|
**Но:** Обычно этого можно достичь и без вынесения в отдельный пакет.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ❌ Когда выносить НЕ нужно (ваш случай)
|
|||
|
|
|
|||
|
|
### 1. Один проект использует database
|
|||
|
|
|
|||
|
|
**Текущая ситуация:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
mnemo_cards_backend/
|
|||
|
|
├── lib/
|
|||
|
|
│ ├── database/ ← Используется ТОЛЬКО здесь
|
|||
|
|
│ │ ├── database.dart
|
|||
|
|
│ │ ├── tables/
|
|||
|
|
│ │ └── daos/
|
|||
|
|
│ ├── api/ ← Использует database
|
|||
|
|
│ ├── user/ ← Использует database
|
|||
|
|
│ └── packs/ ← Использует database
|
|||
|
|
└── pubspec.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Почему не нужно выносить:**
|
|||
|
|
- ❌ Нет переиспользования (только один потребитель)
|
|||
|
|
- ❌ Усложняет структуру проекта без выгоды
|
|||
|
|
- ❌ Больше файлов для навигации
|
|||
|
|
- ❌ Дополнительные настройки pubspec.yaml
|
|||
|
|
- ❌ Усложняет рефакторинг (нужно менять два пакета)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. Тесная связанность с бизнес-логикой
|
|||
|
|
|
|||
|
|
**В вашем проекте database тесно связана с backend:**
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// database используется ВЕЗДЕ в backend
|
|||
|
|
lib/api/v2/users_api_v2.dart → database
|
|||
|
|
lib/user/user_manager.dart → database
|
|||
|
|
lib/packs/pack_manager.dart → database
|
|||
|
|
lib/api/purchase/payment_manager.dart → database
|
|||
|
|
lib/cron/*.dart → database
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Проблемы при выносе:**
|
|||
|
|
|
|||
|
|
1. **Циклические зависимости:**
|
|||
|
|
```
|
|||
|
|
mnemo_cards_database/
|
|||
|
|
└── нужно что-то из mnemo_cards_backend (конвертеры, хелперы)
|
|||
|
|
|
|||
|
|
mnemo_cards_backend/
|
|||
|
|
└── зависит от mnemo_cards_database
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **Конвертеры и extensions:**
|
|||
|
|
```dart
|
|||
|
|
// Где должны быть эти extensions?
|
|||
|
|
extension UserToUserModel on User { ... } // В database или backend?
|
|||
|
|
extension CardPackToCardPackModel on CardPack { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
3. **Зависимости:**
|
|||
|
|
```dart
|
|||
|
|
// database.dart использует converters.dart
|
|||
|
|
// converters.dart может использовать что-то из backend
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3. Database специфична для backend
|
|||
|
|
|
|||
|
|
**В вашем проекте:**
|
|||
|
|
- Database структура создана специально для backend логики
|
|||
|
|
- Таблицы отражают бизнес-логику backend
|
|||
|
|
- DAO методы оптимизированы под нужды backend
|
|||
|
|
- Нет планов использовать в других проектах
|
|||
|
|
|
|||
|
|
**Если database специфична для одного проекта - выносить не стоит.**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Сравнение: Ваш проект vs Когда нужно выносить
|
|||
|
|
|
|||
|
|
| Критерий | Ваш проект | Когда нужно выносить |
|
|||
|
|
|----------|------------|---------------------|
|
|||
|
|
| **Количество потребителей** | 1 (только backend) | 3+ проекта |
|
|||
|
|
| **Микросервисы** | Нет | Да, несколько сервисов |
|
|||
|
|
| **Общая БД** | Одна БД для backend | Одна БД для многих сервисов |
|
|||
|
|
| **Переиспользование** | Нет | Да, используется в разных местах |
|
|||
|
|
| **Независимая разработка** | Нет | Да, разные команды |
|
|||
|
|
| **Версионирование** | Одно с backend | Отдельное версионирование |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Альтернативы вынесению
|
|||
|
|
|
|||
|
|
### 1. Модульная структура внутри проекта
|
|||
|
|
|
|||
|
|
**Вместо отдельного пакета, используйте модульную структуру:**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
mnemo_cards_backend/
|
|||
|
|
├── lib/
|
|||
|
|
│ ├── database/ ← Database модуль (НЕ отдельный пакет)
|
|||
|
|
│ │ ├── database.dart
|
|||
|
|
│ │ ├── tables/
|
|||
|
|
│ │ └── daos/
|
|||
|
|
│ ├── api/ ← API модуль
|
|||
|
|
│ ├── user/ ← User модуль
|
|||
|
|
│ └── packs/ ← Packs модуль
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Плюсы:**
|
|||
|
|
- ✅ Четкое разделение ответственности
|
|||
|
|
- ✅ Легко навигироваться
|
|||
|
|
- ✅ Нет проблем с зависимостями
|
|||
|
|
- ✅ Можно вынести позже, если понадобится
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2. Barrel exports для изоляции
|
|||
|
|
|
|||
|
|
**Создайте единую точку входа для database:**
|
|||
|
|
|
|||
|
|
```dart
|
|||
|
|
// lib/database/database.dart
|
|||
|
|
export 'database_impl.dart';
|
|||
|
|
export 'daos/user_dao.dart';
|
|||
|
|
export 'daos/pack_dao.dart';
|
|||
|
|
// ...
|
|||
|
|
|
|||
|
|
// Использование:
|
|||
|
|
import 'package:mnemo_cards_backend/database/database.dart';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Плюсы:**
|
|||
|
|
- ✅ Чистые импорты
|
|||
|
|
- ✅ Легко рефакторить (меняем только один файл)
|
|||
|
|
- ✅ Можно вынести позже (меняем только exports)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔮 Когда стоит пересмотреть решение
|
|||
|
|
|
|||
|
|
### Если появятся:
|
|||
|
|
|
|||
|
|
1. **Второй backend сервис:**
|
|||
|
|
```
|
|||
|
|
mnemo_cards_backend_api/ ← Основной API
|
|||
|
|
mnemo_cards_backend_admin/ ← Admin API
|
|||
|
|
```
|
|||
|
|
→ Тогда имеет смысл вынести общую database
|
|||
|
|
|
|||
|
|
2. **Отдельные инструменты:**
|
|||
|
|
```
|
|||
|
|
mnemo_cards_migration_tool/ ← Миграции
|
|||
|
|
mnemo_cards_analytics/ ← Аналитика
|
|||
|
|
```
|
|||
|
|
→ Тогда имеет смысл вынести database
|
|||
|
|
|
|||
|
|
3. **Публикация как библиотека:**
|
|||
|
|
- Если планируется публикация на pub.dev
|
|||
|
|
→ Тогда нужно вынести в отдельный пакет
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 Рекомендации для вашего проекта
|
|||
|
|
|
|||
|
|
### ✅ Что делать СЕЙЧАС:
|
|||
|
|
|
|||
|
|
1. **Оставить database внутри backend:**
|
|||
|
|
```
|
|||
|
|
mnemo_cards_backend/
|
|||
|
|
└── lib/
|
|||
|
|
└── database/ ← Остается здесь
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
2. **Использовать модульную структуру:**
|
|||
|
|
- Четко разделять database, api, user, packs модули
|
|||
|
|
- Использовать barrel exports для чистоты импортов
|
|||
|
|
|
|||
|
|
3. **Документировать архитектуру:**
|
|||
|
|
- Описать модульную структуру
|
|||
|
|
- Объяснить, когда и как выносить в отдельный пакет
|
|||
|
|
|
|||
|
|
### ❌ Что НЕ делать:
|
|||
|
|
|
|||
|
|
1. ❌ Не выносить database в отдельный пакет без необходимости
|
|||
|
|
2. ❌ Не усложнять структуру без реальной выгоды
|
|||
|
|
3. ❌ Не создавать лишние абстракции
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 Вывод
|
|||
|
|
|
|||
|
|
### Для вашего проекта: НЕ ВЫНОСИТЬ
|
|||
|
|
|
|||
|
|
**Причины:**
|
|||
|
|
1. ✅ Database используется только в одном проекте (backend)
|
|||
|
|
2. ✅ Тесная связанность с бизнес-логикой backend
|
|||
|
|
3. ✅ Нет планов на переиспользование
|
|||
|
|
4. ✅ Вынос усложнит структуру без выгоды
|
|||
|
|
|
|||
|
|
### Когда пересмотреть решение:
|
|||
|
|
|
|||
|
|
1. 🔄 Появится второй сервис, использующий ту же БД
|
|||
|
|
2. 🔄 Появится отдельный инструмент (admin, analytics)
|
|||
|
|
3. 🔄 Планируется публикация database как библиотеки
|
|||
|
|
4. 🔄 Разные команды будут работать с database независимо
|
|||
|
|
|
|||
|
|
### Альтернатива:
|
|||
|
|
|
|||
|
|
✅ Используйте **модульную структуру** внутри проекта:
|
|||
|
|
- Четкое разделение модулей
|
|||
|
|
- Barrel exports для изоляции
|
|||
|
|
- Легко вынести позже, если понадобится
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Итог:** Ваша текущая структура правильная для проекта с одним backend. Выносить database в отдельный пакет стоит только когда появится реальная необходимость (несколько потребителей, переиспользование).
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|