← Назад к вопросам

Какие использовал паттерны разработки?

2.0 Middle🔥 191 комментариев
#ООП и паттерны проектирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Распространённые паттерны разработки в C# Backend

За свою практику разработки на C# я активно применял паттерны проектирования (Design Patterns), которые можно разделить на три основные категории: порождающие, структурные и поведенческие. Их использование позволяет создавать гибкий, поддерживаемый и масштабируемый код.

1. Порождающие паттерны (Creational Patterns)

Эти паттерны отвечают за создание объектов, обеспечивая гибкость и инкапсуляцию процесса инстанцирования.

  • Singleton (Одиночка) — гарантирует существование только одного экземпляра класса, что критично для логгеров, конфигураторов или пулов соединений с БД. В современных приложениях предпочитаю использовать внедрение зависимостей (DI) через контейнеры (например, в ASP.NET Core), который по умолчанию управляет временем жизни сервисов как Singleton.

    public sealed class Logger
    {
        private static Logger _instance;
        private static readonly object _lock = new object();
    
        private Logger() { }
    
        public static Logger Instance
        {
            get
            {
                lock (_lock)
                {
                    return _instance ??= new Logger();
                }
            }
        }
    }
    
  • Factory Method (Фабричный метод) — определяет интерфейс для создания объектов, но позволяет подклассам изменять тип создаваемых объектов. Часто применяю для создания специфических репозиториев или стратегий обработки данных.

    public abstract class DocumentProcessor
    {
        public abstract IDocument CreateDocument();
    }
    
    public class PdfProcessor : DocumentProcessor
    {
        public override IDocument CreateDocument() => new PdfDocument();
    }
    
  • Dependency Injection (Внедрение зависимостей) — хотя формально это не классический GoF-паттерн, он стал фундаментальным в современной разработке на C#. Позволяет инвертировать контроль над зависимостями, упрощая тестирование и повышая модульность.

2. Структурные паттерны (Structural Patterns)

Они помогают организовать классы и объекты в более крупные структуры, сохраняя гибкость и эффективность.

  • Repository (Репозиторий) — абстрагирует доступ к данным, инкапсулируя логику работы с источником данных (БД, внешний API). Это один из ключевых паттернов в архитектуре Clean Architecture или Domain-Driven Design (DDD), который я активно применяю.

    public interface IUserRepository
    {
        Task<User> GetByIdAsync(int id);
        Task AddAsync(User user);
    }
    
    public class UserRepository : IUserRepository
    {
        private readonly AppDbContext _context;
    
        public UserRepository(AppDbContext context) => _context = context;
    
        public async Task<User> GetByIdAsync(int id) => await _context.Users.FindAsync(id);
    }
    
  • Adapter (Адаптер) — преобразует интерфейс одного класса в интерфейс, ожидаемый клиентом. Использовал при интеграции со сторонними библиотеками или устаревшими системами.

  • Decorator (Декоратор) — динамически добавляет новую функциональность объектам, оборачивая их. Например, для кэширования или логирования вызовов методов без изменения основного кода.

3. Поведенческие паттерны (Behavioral Patterns)

Эти паттерны отвечают за эффективное взаимодействие и распределение ответственности между объектами.

  • Strategy (Стратегия) — определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Идеально подходит для реализации различных правил валидации, способов оплаты или алгоритмов расчёта.

    public interface IPaymentStrategy
    {
        void ProcessPayment(decimal amount);
    }
    
    public class CreditCardPayment : IPaymentStrategy
    {
        public void ProcessPayment(decimal amount) { /* Логика оплаты картой */ }
    }
    
    public class PaymentContext
    {
        private IPaymentStrategy _strategy;
        public void SetStrategy(IPaymentStrategy strategy) => _strategy = strategy;
        public void ExecutePayment(decimal amount) => _strategy?.ProcessPayment(amount);
    }
    
  • Observer (Наблюдатель) — определяет зависимость "один-ко-многим" между объектами так, что при изменении состояния одного объекта все зависящие от него объекты уведомляются. Реализовывал через события C# или интерфейсы для систем уведомлений или обработки доменных событий.

  • Mediator (Посредник) — упрощает взаимодействие множества объектов, централизуя его в одном объекте-посреднике. В ASP.NET Core MediatR библиотека часто используется для реализации этого паттерна, особенно в CQRS-архитектурах.

4. Архитектурные паттерны и подходы

Помимо классических паттернов GoF, я широко применяю более высокоуровневые архитектурные паттерны:

  • CQRS (Command Query Responsibility Segregation) — разделение операций чтения и записи данных для повышения производительности и масштабируемости.
  • Unit of Work (Единица работы) — часто используется вместе с Repository для управления транзакциями и сохранения целостности данных.
  • Specification (Спецификация) — инкапсулирует бизнес-правила, которые можно комбинировать, что особенно полезно в сложных фильтрациях данных.

Заключение

Выбор паттернов всегда зависит от конкретной задачи, требований к масштабируемости и поддерживаемости. В современных микросервисных архитектурах на C# я комбинирую Repository, CQRS, Dependency Injection и Strategy, чтобы обеспечить чистоту кода, лёгкость тестирования и гибкость при изменениях бизнес-требований. Паттерны — это не догма, а инструменты, которые нужно применять обоснованно, чтобы избежать излишнего усложнения системы.