1 9.7K ru

Структурные паттерны: Заместитель (Proxy) C#

Categories: 💻 Programming

Назначение:

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

Proxy (заместитель)  — ​ является суррогатом другого объекта и контролирует доступ к нему.​

Когда использовать Proxy?

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

  • Удаленный заместитель (remote proxies) — ​отвечает за кодирование запроса и его аргументов для работы с компонентом в другом адресном пространстве.

  • Виртуальный заместитель (virtual proxies) —​ может кэшировать дополнительную информацию о реальном компоненте, чтобы отложить его создание.

  • Защищающий заместитель (protection proxies) — проверяет, имеет ли вызывающий объект необходимые для выполнения запроса права.​ 

 

UML схема паттерна Заместитель​:

UML схема паттерна Заместитель​

Участники 

  • Subject: определяет общий интерфейс для Proxy и RealSubject. Поэтому Proxy может использоваться вместо RealSubject

  • RealSubject: представляет реальный объект, для которого создается прокси

  • Proxy: заместитель реального объекта. Хранит ссылку на реальный объект, контролирует к нему доступ, может управлять его созданием и удалением.

  • Client: использует объект Proxy для доступа к объекту RealSubject

Реализация шаблона заместитель на C#

class Client
{
    void Main()
    {
        Subject subject = new Proxy();
        subject.Request();
    }
}
abstract class Subject
{
    public abstract void Request();
}
 
class RealSubject : Subject
{
    public override void Request()
    {}
}
class Proxy : Subject
{
    RealSubject realSubject;
    public override void Request()
    {
        if (realSubject == null)
            realSubject = new RealSubject();
        realSubject.Request();
    }
}

Схема примера использования паттерна proxy из реальной жизни:

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

Схема примера использования паттерна proxyиз реальной жизни

 

Обсуждение паттерна Proxy

Заместитель vs. декоратор

Структуры паттернов «Заместитель» и «Декоратор» очень похожи. Каждый из них содержит ссылку на базовый компонент и делегирует ему выполнение всей работы. Но у этих паттернов разное назначение.​

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

Виртуальный заместитель и Lazy

Класс Lazy можно считать универсальным строительным блоком, с помощью которого легко создавать виртуальные классы-заместители

public interface IHeavyweight
    {
        void Foo();
    }
   
    public class Heavyweight : IHeavyweight
    {
        public void Foo()
        { }
    }
    // Виртуальный заместитель, который будет создавать
    // тяжеловесный объект лишь при необходимости
    public class HeavyweightProxy : IHeavyweight
    {
        private readonly Lazy<Heavyweight> _lazy = new Lazy<Heavyweight>();
        public void Foo()
        {
            _lazy.Value.Foo();
        }
    }

Примеры в .NET Framework

  1. Удаленные классы-заместители. В коммуникационных технологиях в .NET Framework применяются удаленные прокси-классы: ChannelBase в WCF, RealProxy в .NETRemoting
  2. Виртуальные классы-заместители в ORM-фреймворках. В современных ORM (Object-RelationalMapping — объектно-реляционное отображение), таких как NHibernate или EntityFramework, применяются специализированные виртуальные классы-заместители. ORM генерирует оболочку над сущностями (dataentities), чтобы отслеживать изменения и генерировать корректный SQL-код для обновле- ния записей в базе данных.

Comments:

Please log in to be able add comments.
👍