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

Какие знаешь структурные паттерны проектирования?

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

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

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

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

Структурные паттерны проектирования в C#

Структурные паттерны — это шаблоны проектирования, которые упрощают построение сложных объектных структур за счёт композиции классов и объектов. Они помогают обеспечить гибкость и эффективность системы, управляя отношениями между сущностями. Вот основные структурные паттерны, которые я применяю в C# Backend-разработке:

1. Адаптер (Adapter)

Паттерн Адаптер позволяет объектам с несовместимыми интерфейсами работать вместе. Он оборачивает несовместимый объект и предоставляет совместимый интерфейс. В C# часто используется для интеграции сторонних библиотек или устаревшего кода.

// Целевой интерфейс
public interface ILogger
{
    void Log(string message);
}

// Адаптируемый класс
public class FileLoggerLegacy
{
    public void WriteToFile(string text)
    {
        File.WriteAllText("log.txt", text);
    }
}

// Адаптер
public class FileLoggerAdapter : ILogger
{
    private readonly FileLoggerLegacy _legacyLogger;
    
    public FileLoggerAdapter(FileLoggerLegacy legacyLogger)
    {
        _legacyLogger = legacyLogger;
    }
    
    public void Log(string message)
    {
        _legacyLogger.WriteToFile($"[{DateTime.Now}] {message}");
    }
}

// Использование
var legacyLogger = new FileLoggerLegacy();
ILogger logger = new FileLoggerAdapter(legacyLogger);
logger.Log("Привет, мир!");

2. Мост (Bridge)

Паттерн Мост разделяет абстракцию и реализацию, позволяя им изменяться независимо. Это особенно полезно для поддержки множественных платформ или реализаций.

// Реализация
public interface IRenderer
{
    void RenderCircle(float radius);
}

public class VectorRenderer : IRenderer
{
    public void RenderCircle(float radius)
    {
        Console.WriteLine($"Рисуем круг радиусом {radius} в векторном формате");
    }
}

public class RasterRenderer : IRenderer
{
    public void RenderCircle(float radius)
    {
        Console.WriteLine($"Рисуем пиксели круга радиусом {radius}");
    }
}

// Абстракция
public abstract class Shape
{
    protected IRenderer renderer;
    
    protected Shape(IRenderer renderer)
    {
        this.renderer = renderer;
    }
    
    public abstract void Draw();
}

public class Circle : Shape
{
    private float radius;
    
    public Circle(float radius, IRenderer renderer) : base(renderer)
    {
        this.radius = radius;
    }
    
    public override void Draw()
    {
        renderer.RenderCircle(radius);
    }
}

3. Компоновщик (Composite)

Паттерн Компоновщик позволяет сгруппировать объекты в древовидные структуры и работать с ними как с единым объектом. Идеально подходит для иерархических данных.

public interface IGraphic
{
    void Draw();
    void Move(int x, int y);
}

public class Circle : IGraphic
{
    public void Draw() => Console.WriteLine("Рисуем круг");
    public void Move(int x, int y) => Console.WriteLine($"Перемещаем круг на ({x},{y})");
}

public class CompositeGraphic : IGraphic
{
    private List<IGraphic> _children = new List<IGraphic>();
    
    public void Add(IGraphic graphic) => _children.Add(graphic);
    public void Remove(IGraphic graphic) => _children.Remove(graphic);
    
    public void Draw()
    {
        foreach (var child in _children)
            child.Draw();
    }
    
    public void Move(int x, int y)
    {
        foreach (var child in _children)
            child.Move(x, y);
    }
}

4. Декоратор (Decorator)

Паттерн Декоратор динамически добавляет объекту новые обязанности, предоставляя гибкую альтернативу наследованию. В ASP.NET Core активно используется в Middleware.

public interface INotifier
{
    void Send(string message);
}

public class EmailNotifier : INotifier
{
    public void Send(string message)
    {
        Console.WriteLine($"Отправка email: {message}");
    }
}

public abstract class NotifierDecorator : INotifier
{
    protected INotifier _notifier;
    
    protected NotifierDecorator(INotifier notifier)
    {
        _notifier = notifier;
    }
    
    public virtual void Send(string message)
    {
        _notifier.Send(message);
    }
}

public class SMSNotifierDecorator : NotifierDecorator
{
    public SMSNotifierDecorator(INotifier notifier) : base(notifier) {}
    
    public override void Send(string message)
    {
        base.Send(message);
        Console.WriteLine($"Отправка SMS: {message}");
    }
}

5. Фасад (Facade)

Паттерн Фасад предоставляет упрощённый интерфейс к сложной подсистеме, скрывая её внутреннюю сложность.

// Сложная подсистема
public class DatabaseService
{
    public void Connect() => Console.WriteLine("Подключение к БД");
    public void Query(string sql) => Console.WriteLine($"Выполнение запроса: {sql}");
}

public class CacheService
{
    public void Set(string key, object value) => Console.WriteLine($"Кэширование: {key}");
    public object Get(string key) => null;
}

// Фасад
public class DataAccessFacade
{
    private DatabaseService _db;
    private CacheService _cache;
    
    public DataAccessFacade()
    {
        _db = new DatabaseService();
        _cache = new CacheService();
    }
    
    public object GetData(string key)
    {
        var data = _cache.Get(key);
        if (data == null)
        {
            _db.Connect();
            _db.Query($"SELECT * FROM data WHERE key='{key}'");
            data = new object();
            _cache.Set(key, data);
        }
        return data;
    }
}

6. Приспособленец (Flyweight)

Паттерн Приспособленец позволяет эффективно поддерживать множество мелких объектов, разделяя общее состояние между ними. Экономит память за счёт кэширования.

public class FlyweightFactory
{
    private Dictionary<string, IFlyweight> _flyweights = new();
    
    public IFlyweight GetFlyweight(string key)
    {
        if (!_flyweights.ContainsKey(key))
            _flyweights[key] = new ConcreteFlyweight(key);
        
        return _flyweights[key];
    }
}

public interface IFlyweight
{
    void Operation(string extrinsicState);
}

7. Заместитель (Proxy)

Паттерн Заместитель предоставляет суррогатный объект, контролирующий доступ к другому объекту. Используется для ленивой инициализации, кэширования, контроля доступа.

public interface ISubject
{
    void Request();
}

public class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("Выполнение реального запроса...");
    }
}

public class Proxy : ISubject
{
    private RealSubject _realSubject;
    
    public void Request()
    {
        if (_realSubject == null)
            _realSubject = new RealSubject();
        
        Console.WriteLine("Проверка доступа...");
        _realSubject.Request();
        Console.WriteLine("Логирование запроса...");
    }
}

Практическое применение в Backend-разработке

В C# Backend-разработке структурные паттерны решают критически важные задачи:

  • Адаптеры для интеграции с внешними API и устаревшими системами
  • Декораторы в Middleware ASP.NET Core для добавления функциональности (аутентификация, логирование, кэширование)
  • Фасады для упрощения работы со сложными модулями (ORM, кэширование, очереди сообщений)
  • Прокси для реализации ленивой загрузки данных, кэширования и контроля доступа
  • Компоновщики для построения иерархических структур (меню, разрешения, организационные структуры)

Наиболее часто я использую Декоратор (для Middleware), Адаптер (для интеграций) и Фасад (для упрощения сложных подсистем). Правильное применение структурных паттернов позволяет создавать гибкие, поддерживаемые и масштабируемые backend-системы на C#.

Какие знаешь структурные паттерны проектирования? | PrepBro