Vertical Slice Architecture

↑ 8.2 Архитектурные стили и DDD · ← Предыдущая · → Следующая

Обязательно~4 мин чтенияУровень: senior

Зачем это на собесе

Современная альтернатива слоям: организация кода по фичам.

Объяснение

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

Features/
  Orders/
    CreateOrder/
      CreateOrder.cs          # Request, Validator, Handler, Endpoint — рядом
    GetOrder/
      GetOrder.cs
    CancelOrder/
      CancelOrder.cs
  Customers/
    ...
Common/                       # только действительно общее
public static class CreateOrder
{
    public record Command(Guid CustomerId, List<Item> Items);
    public class Validator : AbstractValidator<Command> { /* ... */ }
 
    public class Handler(AppDbContext db, TimeProvider clock)
    {
        public async Task<Guid> Handle(Command c, CancellationToken ct)
        {
            var order = Order.Create(c.CustomerId, c.Items, clock.GetUtcNow());
            db.Orders.Add(order);
            await db.SaveChangesAsync(ct);
            return order.Id;
        }
    }
 
    public static void Map(IEndpointRouteBuilder app) =>
        app.MapPost("/orders", async (Command c, Handler h, CancellationToken ct) => Results.Created($"/orders/{await h.Handle(c, ct)}", null));
}
АспектСлоиVertical Slice
Изменение фичимного файлов в разных папкахвсё в одном месте
Общий кодслой сервисов, репозиторииминимально, выделяется по необходимости
Технологии на срезединые для всехможно разные (EF для записи, Dapper для чтения)
Риск«толстые» слоидублирование между срезами

Подходит вместе с CQRS и MediatR/Wolverine; в каждом срезе допускается разная сложность.

Нюансы и подводные камни

  • Дублирование между срезами допустимо, пока не возникает общее правило — выносите в домен.
  • Бизнес-инварианты нужно держать в доменной модели, иначе они разбредутся по срезам.
  • Слишком много «общего» вновь создаёт слои.
  • Требует договорённости о структуре папок и именовании.

Практика

  1. Перенесите два use case с раскладки по слоям на срезы.
  2. Используйте Dapper для чтения в срезе списка и EF для записи.
  3. Оцените, сколько файлов меняется при добавлении поля.

Вопросы с ответами

Связанные темы