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

Что такое паттерн проектирования Proxy?

2.0 Middle🔥 182 комментариев
#ASP.NET и Web API#Основы C# и .NET

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

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

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

Что такое паттерн проектирования Proxy (Заместитель)?

Proxy — это структурный паттерн проектирования, который предоставляет объект-заместитель или суррогат для другого объекта. Основная цель — контролировать доступ к оригинальному объекту, добавляя промежуточный уровень. Это позволяет реализовать дополнительную логику, например, отложенную инициализацию, контроль доступа, логирование или кэширование, без изменения кода исходного объекта.

Основная идея и назначение

Паттерн Proxy используется, когда необходимо:

  • Контролировать доступ к объекту (например, проверка прав доступа).
  • Оптимизировать работу с объектом (например, кэширование результатов).
  • Упрощать интерфейс или добавлять дополнительную логику перед или после вызовов методов целевого объекта.
  • Работать с удаленными объектами (например, в распределенных системах, где используется Remote Proxy).

Типы прокси

Существует несколько классических видов прокси, каждый решает специфическую задачу:

1. Virtual Proxy (Виртуальный прокси)

Откладывает создание дорогостоящего объекта до момента его фактического использования. Это полезно для экономии ресурсов.

2. Protection Proxy (Защищающий прокси)

Контролирует доступ к объекту, проверяя права или условия перед выполнением операции.

3. Remote Proxy (Удаленный прокси)

Представляет локальный заместитель для объекта, находящегося в другом адресном пространстве (например, на другом сервере). Широко используется в клиент-серверных архитектурах.

4. Smart Proxy (Умный прокси)

Добавляет дополнительные действия при обращении к объекту, например, подсчет количества ссылок, блокировка от изменений или логирование.

5. Cache Proxy (Кэширующий прокси)

Кэширует результаты вызовов методов, чтобы избежать повторных вычислений или запросов.

Реализация паттерна Proxy в C#

В основе паттерна лежит создание класса-заместителя, который реализует тот же интерфейс, что и целевой объект. Прокси содержит ссылку на реальный объект и перехватывает вызовы его методов, добавляя свою логику.

Рассмотрим пример Protection Proxy для системы управления документами.

// Интерфейс, который реализует реальный объект и прокси
public interface IDocumentAccess
{
    void ViewDocument();
    void EditDocument();
}

// Реальный объект (Subject)
public class Document : IDocumentAccess
{
    private string _content;

    public Document(string content)
    {
        _content = content;
    }

    public void ViewDocument()
    {
        Console.WriteLine($"Просмотр документа: {_content}");
    }

    public void EditDocument()
    {
        Console.WriteLine("Редактирование документа выполнено.");
    }
}

// Proxy-объект, контролирующий доступ
public class DocumentProxy : IDocumentAccess
{
    private Document _realDocument;
    private string _userRole;

    public DocumentProxy(string content, string userRole)
    {
        _realDocument = new Document(content);
        _userRole = userRole;
    }

    public void ViewDocument()
    {
        // Все пользователи могут просматривать
        _realDocument.ViewDocument();
    }

    public void EditDocument()
    {
        // Проверка прав доступа перед редактированием
        if (_userRole == "Admin")
        {
            _realDocument.EditDocument();
        }
        else
        {
            Console.WriteLine("Ошибка: недостаточно прав для редактирования.");
        }
    }
}

// Клиентский код
class Program
{
    static void Main()
    {
        // Прокси для пользователя с ролью "User"
        IDocumentAccess userDoc = new DocumentProxy("Конфиденциальный текст", "User");
        userDoc.ViewDocument(); // Успешно
        userDoc.EditDocument(); // Ошибка доступа

        // Прокси для администратора
        IDocumentAccess adminDoc = new DocumentProxy("Конфиденциальный текст", "Admin");
        adminDoc.ViewDocument(); // Успешно
        adminDoc.EditDocument(); // Успешно
    }
}

Преимущества и недостатки паттерна Proxy

Преимущества:

  • Позволяет контролировать доступ к объекту без изменения его кода.
  • Улучшает производительность через кэширование или отложенную инициализацию.
  • Обеспечивает дополнительную безопасность через проверку прав.
  • Упрощает работу с удаленными или сложными системами.
  • Снижает связность клиентского кода с реальным объектом.

Недустатки:

  • Увеличивает сложность системы из-за добавления дополнительных классов.
  • Может замедлить выполнение из-за дополнительных проверок, если прокси используется некорректно.
  • Иногда приводит к дублированию интерфейсов, особенно при необходимости полного соответствия с оригинальным объектом.

Proxy vs. Decorator и Adapter

Паттерны Proxy, Decorator и Adapter схожи структурно, но имеют разные цели:

  • Adapter изменяет интерфейс объекта для совместимости с другим кодом.
  • Decorator динамически добавляет новые обязанности объекту, расширяя его функциональность.
  • Proxy контролирует доступ к объекту, не изменяя его основного поведения и интерфейса.

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

В разработке backend систем на C# паттерн Proxy часто используется в следующих сценариях:

  • Аутентификация и авторизация: защищающие прокси для API endpoints или сервисов.
  • Кэширование данных: прокси для репозиторий или сервисов доступа к данным, которые кэшируют результаты запросов к базе данных.
  • Логирование и мониторинг: умные прокси для записи логов вызовов методов критических сервисов.
  • Работа с внешними API: удаленные или защищающие прокси для клиентов внешних сервисов, добавляющие обработку ошибок или трансформацию данных.
  • Lazy Loading в ORM: виртуальные прокси для сущностей в Entity Framework, которые откладывают загрузку связанных данных до момента обращения.

Использование Proxy позволяет строить более гибкие, безопасные и эффективные архитектуры, разделяя ответственности и соблюдая принципы SOLID, особенно принцип Open/Closed (система открыта для расширения, но закрыта для изменений).

Что такое паттерн проектирования Proxy? | PrepBro