1. Начало: логика в контроллерах или сервисах

Ссылки

Плюсы

  • Просто
  • Лучшая возможная производительность

Минусы

  • Затраты на поддержку растут с количеством кода; по закону брукса разработка в какой-то момент остановится

2. Вертикальные слайсы / CQRS

Мотивация

2.1 Логика в контроллерах

  • нарушение SRP
  • смешение бизнес логики и инфраструктурного кода
  • затруднено повторное использование

2.2. В сервисах

  • Services, Helpers, Managers, ... повышается связность по мере роста проекта, в итоге имеется тенденция к Big Ball of Mud
  • Cross-cutting concerns
  • Затруднен Feature Toggle и рефакторинг
  • Конфликты при мердже, не соблуюдается принцип OCP
  • Потеря контекста при навигации по файлам

Задача

  • Реализовать вертикальные слайсы без использования внешних библиотек, вроде MediatR или SimpleInjector
  • Или применить одну из них

Ссылки

Доклады

Статьи

Библиотеки

Актуальные техники

Плюсы

  • Меньше конфликтов
  • Больше добавления и удаления кода, меньше редактирования
  • Базовые хендлеры, меньше бойлерплейта
  • Обобщенная обработка Cross-cutting concerns

Минусы

  • Больше инфраструктурного кода
  • Непривычно

3. Модули

Мотивация

  • Циклические зависимости
  • Когнитивная сложность
  • Затруднен рефакторинг
  • Время компиляции, запуска
  • Убрать явную зависимость от конкретной ORM

Задача

Разделить проект на модули (отдельные сборки)

Ссылки

Плюсы

  • Зависимости инвертированы, нет циклических зависимостей
  • Нет зависимостей от конкретной ORM в домене
  • Видны зависимости между модулями

Минусы

  • Больше абстраций
  • Больше инфраструктурного кода
  • Нужны Domain Events

4. Rich Domain Model

Мотивация

Задача

  • Применить инкапсуляцию
  • Создать спецификации
  • Удалить <FK>Id-properties
  • Определить конструкторы с параметрами
  • Выделить методы сущностей

Ссылки

Плюсы

  • Защита от NRE
  • Соблюдение инвариантов
  • Лучшая читаемость кода
  • Следование принципам ООП

Минусы

  • Возможное дублирование валидации в конструкторах и в валидаторах
  • Ухудшение производительности
  • Сложность моделирования
  • Куда мне класть этот метод?

5. Контексты операций

Мотивация

  • Дублирование кода в валидаторах/контроллера
  • Повторные загрузки сущностей
  • Создание обобщенных валидаторов

Задача

  • Написать фабрику контекстов
  • Написать обобщенные валидаторы

Плюсы

  • Нет повторных чтений из БД
  • Обобщенная валидация

Минусы

6. State

Мотивация

Задача

  • Объединить паттерн State и идеи функционального программирования
  • Запрограммировать конечный автомат

Ссылки

Плюсы

  • Комплируется - значит работает
  • Переходы между состояниями и правила - явные

Минусы

  • Смешение ответственности между валидаторами и State

7. Domain Services

Мотивация

Задача

  • Перенести работу с IO в отдельный слой
  • Не потерять преимущества обобщенных интерфейсов, но сохранить холистические абстракции

Ссылки

Плюсы

  • Более формальные правила структурирования кода
  • Упрощение тестирования

Минусы

  • Фрагментация логики

8. Domain Events

Мотивация

  • Отделение мух от котлет основного процесса от побочных эффектов
  • Коммуникация между модулями
  • Упрощение перехода к шине данных и микросервисам
  • Аудит лог

Задача

  • Запрограммировать диспетчер
  • Заменить прямую работу с DbContext на UnitOfWork

Ссылки

Плюсы

  • Слабая связанность

Минусы

  • Неявность
  • Управление транзакциями
  • События в обработчиках событий
  • Синхронные и асинхронные обработчики

9. Массовые операции

Мотивация

  • Производительность: импорт, экспорт, массовое обновление, денормализация

Задача

  • Реализовать массовую операцию
  • Подписаться на событие одного модуля и обработать его в другом

Ссылки

Плюсы

  • Не нужно писать хранимые процедуры

Минусы