Рекомендации по названию папки для общей логики в Clean Architecture
Главное предупреждение: антипаттерн «Shared/Common/Utils»
Согласно исследованиям (Medium «The Shared Folder Anti-Pattern», Milan Jovanovic «Vertical Slice Architecture»), папки с названиями Shared, Common, Utils, Helpers, Misc чаще всего превращаются в «мусорный ящик» (junk drawer). В них попадает несвязанный код с разными циклами изменений, что в итоге нарушает:
- Dependency Inversion — прикладная логика начинает напрямую зависеть от инфраструктуры (SMTP, JWT, FileSystem, БД);
- SRP — классы-хелперы делают слишком много всего;
- Тестируемость — статические методы нельзя замокать;
- Архитектурные границы — логика утекает между слоями.
Правильный подход: деление по ответственности, а не по «общности»
Вместо одной папки «для всего общего», Clean Architecture предполагает распределение кода по слоям:
src/
├── Domain/ # Бизнес-сущности, value objects, доменные события
├── Application/ # Use cases (команды/запросы), интерфейсы сервисов
├── Infrastructure/ # Реализация: БД, API, файлы, JWT, почта
├── Api/ # Тонкий слой хоста, composition root
└── Shared.Kernel/ # (опционально) сквозные примитивы: Result, ValidationКонкретные рекомендации под вашу задачу
Для «разной логики обработки данных + доп. файлов + общего»:
| Тип кода | Где хранить | Пример названия |
|---|---|---|
| Чистые утилиты (без состояния, без I/O) — форматтеры, конвертеры enum, парсеры | Рядом с данными, которыми они оперируют | Domain/Utils/ или Application/Utils/ |
| Доменная бизнес-логика (расчёты, правила) | Внутрь сущностей и value objects | Domain/Services/ (только если не помещается в сущность) |
| Use cases (оркестрация) | Application слой | Application/Features/<Feature>/ |
| Инфраструктурные сервисы (БД, файлы, внешние API) | Implementation в Infrastructure, interface в Application | Infrastructure/Persistence/, Infrastructure/Files/ |
| Сквозные примитивы (Result, Maybe, Validation) | Опциональный Shared.Kernel | Shared.Kernel/ |
| Логика, общая для связанных фичей | Локальная папка Shared внутри фичи | Features/Orders/Shared/ |
Рекомендуемое название для вашего случая
Если вам нужна именно одна папка для «разной логики обработки данных + доп. файлов + общего», лучшим вариантом из худших будет:
✅ Infrastructure/ (с подразделами по типу обработки)
Infrastructure/
├── DataProcessing/ # Скрипты и пайплайны обработки данных
├── Persistence/ # Работа с БД
├── FileStorage/ # Работа с файлами
├── Services/ # Реализация интерфейсов из Application
└── CrossCutting/ # Логирование, кэширование (если не в Shared.Kernel)⚠️ Если хочется отдельную «общую» папку — Shared.Kernel/
Shared.Kernel/
├── Primitives/ # Result, Error, Maybe
├── Conventions/ # Базовые интерфейсы
└── Extensions/ # Расширения без бизнес-логикиВажно: в Shared.Kernel кладите только код без зависимости от фреймворков и инфраструктуры — иначе он тоже превратится в мусорный ящик.
Чек-лист перед добавлением файла в «общую» папку
- Нет ли у этого кода естественного «хозяина»? Если есть — кладите к нему.
- Зависит ли код от I/O или фреймворка? Если да →
Infrastructure/(через интерфейс). - Это чистая бизнес-логика? Если да →
Domain/. - Это сквозной примитив без зависимостей? Тогда →
Shared.Kernel/. - Используется только в одной фиче? Тогда →
Features/<Feature>/Shared/.
Источники
TL;DR: Не создавайте папку Common/Shared/Utils «для всего общего» — это антипаттерн. Разделите по ответственности: Infrastructure/ для обработки данных с I/O, Domain/ для чистой бизнес-логики, опциональный Shared.Kernel/ для сквозных примитивов без зависимостей. Если нужна именно одна папка — используйте Infrastructure/ с подкаталогами по типу обработки.
Идеальное название для вашего случая
То, что вы описываете — чистая трансформация данных (resize, transpose, skip headers, обработка DataTable) без I/O и без владельца — это не антипаттерн «Shared junk drawer». Это легитимная общая логика конкретного bounded context’а (Excel-обработки).
Главное правило Clean Architecture здесь: называйте по ЧТОМУ делает код, а не по тому, КЕМ он используется.
Рекомендация: Excel/Transformations/
Excel/
├── Transformations/ ← ваша общая логика здесь
│ ├── ResizeTable.cs (или .py / .ts)
│ ├── TransposeTable.cs
│ ├── SkipHeaders.cs
│ └── DataTableProcessor.cs
├── Readers/ ← чтение excel (если будет)
├── Writers/ ← запись excel
└── Validators/ ← валидацияПочему Transformations/, а не Shared/ или Common/
| Название | Вердикт | Почему |
|---|---|---|
❌ Shared/ | Антипаттерн | Не говорит, ЧТО внутри; со временем превращается в мусорник |
❌ Common/ | Антипаттерн | То же самое |
❌ Helpers/ | Антипаттерн | Слишком размыто, violate SRP |
❌ Utils/ | Антипаттерн | «Утилиты» — мусорная категория |
⚠️ Core/ | Сомнительно | Звучит как «центр системы», но на деле — то же самое «общее» |
✅ Transformations/ | Рекомендуется | Описывает ЧТО делает код: transform данных |
✅ Operations/ | Хорошо | Чуть шире, если добавятся не-трансформации |
✅ Processing/ | Хорошо | Если хотите акцент на обработке, а не на результате |
✅ Primitives/ | Если чистые building blocks | Уместно для совсем базовых операций |
Если у вас в проекте уже есть слой/модуль Excel
Application/
└── Features/
└── ExcelProcessing/
├── Transformations/ ← общая логика
├── ImportOrders/
├── ExportReport/
└── GenerateTemplate/Если это в Domain-слое (чистая бизнес-логика без I/O)
Раз вы сказали «владелец не нужен, общая штука для всех excelfunction» — это похоже на доменную логику Excel:
Domain/
└── Excel/
└── Transformations/
├── TableResizer.cs
├── TableTransposer.cs
├── HeaderSkipper.cs
└── DataTableProcessor.csФинальный совет
Названия файлов тоже делайте по глаголу/действию, не по «Helper»:
- ✅
TableResizer,TableTransposer,HeaderSkipper - ❌
ExcelHelper,TableUtils,CommonFunctions
TL;DR: Используйте Transformations/ внутри модуля Excel/ (или Domain/Excel/). Это название самодокументируемое, соответствует SRP и не скатится в антипаттерн «junk drawer», потому что категория чётко ограничена — только операции трансформации таблиц.











