TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.75K subscribers
Post #2905 2.65K
День 2415. #ЗаметкиНаПолях
Реальная Цена Абстракций в .NET. Начало
Мы, разработчики, любим абстракции. Репозитории, сервисы, конвертеры, обёртки. Они делают наш код «чистым», обещают тестируемость и дают нам ощущение гибкости. Некоторые абстракции оправдывают себя, изолируя реальную волатильность и защищая систему от изменений. Другие же незаметно увеличивают сложность, замедляют внедрение и скрывают проблемы производительности за слоями косвенности. Рассмотрим, когда абстракции приносят дивиденды, а когда они становятся техническим долгом.

Когда абстракции окупаются
Лучшие абстракции изолируют реальную волатильность — те части вашей системы, которые вы действительно ожидаете изменить. Пример: обработка платежей. Ваша бизнес-логика не должна напрямую зависеть от API или SDK платёжной системы. Если вы когда-нибудь перейдёте на другую, вы не хотите, чтобы это повлияло на множество мест вашей кодовой базы. Здесь абстракция имеет смысл:
public interface IPaymentProcessor
{
Task ProcessAsync(
Order order, CancellationToken ct);
}

public class StripePaymentProcessor
: IPaymentProcessor
{
public async Task ProcessAsync(
Order order, CancellationToken ct)
{
// Реализация для Stripe
}
}

Теперь бизнес-логика может сфокусироваться на домене:
public class CheckoutService(
IPaymentProcessor processor)
{
public Task CheckoutAsync(
Order order, CancellationToken ct) =>
processor.ProcessAsync(order, ct);
}

Эта абстракция изолирует действительно нестабильную зависимость (платёжного провайдера), сохраняя при этом независимость логики оформления заказа. Когда Stripe поменяет свой API или вы поменяете провайдера, нужно изменить только один класс. Это хорошая абстракция. Она даёт опциональность там, где она действительно нужна.

Когда абстракции становятся техническим долгом
Проблемы возникают, когда мы абстрагируем то, что на самом деле не является изменчивым. В итоге мы оборачиваем стабильные библиотеки или создаём слои, которые не приносят реальной ценности. «Чистый» слой, добавленный вами сегодня, завтра становится обузой для обслуживания.

Большинство команд начинают с чего-то разумного:
public interface IUserRepository
{
Task<IEnumerable<User>> GetAllAsync();
}

Но по мере изменения требований, растёт и интерфейс:
public interface IUserRepository
{
Task<IEnumerable<User>> GetAllAsync();
Task<User?> GetByEmailAsync(string email);
Task<IEnumerable<User>> GetActiveUsersAsync();
Task<IEnumerable<User>> GetUsersByRoleAsync(string role);
Task<IEnumerable<User>> SearchAsync(string keyword, int page, int pageSize);
// ...и т.д.
}

Внезапно репозиторий начинает пропускать логику запросов в свой интерфейс. Каждый новый способ получения пользователей означает новый метод, и «абстракция» становится сборищем всевозможных запросов.

Между тем, Entity Framework уже предоставляет всё это через LINQ: строго типизированные запросы, которые напрямую соответствуют SQL. Вместо того, чтобы использовать эту мощь, вы ввели слой косвенности. Паттерн репозитория имел смысл, когда ORM были незрелыми. Сегодня это часто просто формальность.

Частью взросления разработчика является умение распознавать, когда паттерны становятся антипаттернами. Репозитории имеют смысл, когда они инкапсулируют сложную логику запросов или предоставляют унифицированный API для нескольких источников данных. Но вы должны стремиться, чтобы они были сосредоточены на логике предметной области. Как только они разрастаются в мириады методов для каждого возможного запроса, это признак того, что абстракция дала сбой.

Продолжение следует…

Источник:
https://www.milanjovanovic.tech/blog/the-real-cost-of-abstractions-in-dotnet
  • 👍 25
More from @netdeveloperdiary
  1. Oct 2, 2026День 2802. #Карьера #Юмор Секреты Программирования, Известные Только Легендам Ещё один пос…
  2. Oct 1, 2026Post #3357
  3. Sep 30, 2026Post #3356
  4. Sep 29, 2026Фото 3 (с) Анатолий Кулаков
  5. Sep 29, 2026День 2799. Конференция DotNext 2026. Часть 1 25 и 26 сентября в Москве прошла очередная ко…
  6. Sep 28, 2026День 2798. #Оффтоп Утиная Типизация в C# с Помощью Перехватчиков. Часть 2 Некоторое время…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →