Статьи

Gang of Four — шаблон прокси-дизайна

Прокси — это еще один шаблон структурного проектирования, который работает «от имени» или «вместо» другого объекта для доступа к последующему.

Когда использовать этот шаблон?

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

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

  • Виртуальный прокси. Представьте себе ситуацию, когда для извлечения изображения огромного размера требуется несколько вызовов базы данных. Поскольку это дорогостоящая операция, мы можем использовать шаблон прокси, который будет создавать несколько прокси и указывать на объект, потребляющий большой объем памяти, для дальнейшей обработки. Реальный объект создается только тогда, когда клиент сначала запрашивает / получает доступ к объекту, и после этого мы можем просто обратиться к прокси для повторного использования объекта. Это позволяет избежать дублирования объекта и, следовательно, экономить память.
  • Удаленный прокси — можно подумать об удаленной прокси-заглушке в вызове RPC. Удаленный прокси-сервер предоставляет локальное представление объекта, который находится в другом месте адреса. Другим примером может быть предоставление интерфейса для удаленных ресурсов, таких как веб-служба или ресурсы REST.
  • Защитный прокси-сервер — защитный прокси-сервер действует как уровень авторизации, чтобы проверить, имеет ли реальный пользователь доступ к соответствующему контенту. В качестве примера можно привести прокси-сервер, который обеспечивает ограниченный доступ в Интернет в офисе. Только веб-сайты и контент, которые действительны, будут разрешены, а остальные будут заблокированы.
  • Smart Proxy — Smart Proxy обеспечивает дополнительный уровень безопасности, вставляя определенные действия при доступе к объекту. Примером может быть проверка, заблокирован ли реальный объект перед тем, как к нему осуществляется доступ, чтобы убедиться, что никакой другой объект не может его изменить.

Состав:

Структура шаблона Proxy Design

Участники:

  • Тема — Этот объект определяет общий интерфейс для RealSubject и Proxy, так что Proxy можно использовать везде, где ожидается RealSubject.
  • Прокси — он поддерживает ссылку на RealSubject, чтобы Прокси мог получить к нему доступ. Он также реализует тот же интерфейс, что и RealSubject, так что Proxy можно использовать вместо RealSubject. Прокси также контролирует доступ к RealSubject и может создавать или удалять этот объект.
  • RealSubject — относится к основному объекту, который представляет прокси.

Пример:

Мы обсудим два примера в этой статье. Первым будет шаблон виртуального прокси, а другим — шаблон защитного прокси.

Пример виртуального прокси :

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

  • Создайте интерфейс, к которому будет обращаться клиент. Все его методы будут реализованы классом ProxyImage и классом RealImage.
  • RealImage работает в другой системе и содержит информацию об изображении, доступ к которой осуществляется из базы данных.
  • ProxyImage, работающий в другой системе, может представлять RealImage в новой системе. Используя прокси, мы можем избежать многократной загрузки изображения.

Диаграмма классов:

Пример виртуального прокси

Пример кода:

Image.java

1
2
3
public interface Image {
    public void showImage();
}

RealImage.java

01
02
03
04
05
06
07
08
09
10
11
12
public class RealImage implements Image {
 
    private String fileName = null;
    public RealImage(String strFileName){
        this.fileName = strFileName;
    }
    @Override
    public void showImage() {
        System.out.println('Show Image:' +fileName);
 
    }
}

ProxyImage.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public class ProxyImage implements Image {
    private RealImage img= null;
    private String fileName = null;
 
    public ProxyImage(String strFileName) {
        this.fileName = strFileName;
    }
    /*
     * (non-Javadoc)
     * @see com.proxy.virtualproxy.Image#showImage()
     */
    @Override
    public void showImage() {
        if(img == null){
            img = new RealImage(fileName);
        }
        img.showImage();
    }
}

Client.java

1
2
3
4
5
6
7
8
public class Client {
public static void main(String[] args) {
 final Image img1 = new ProxyImage('Image***1');
 final Image img2 = new ProxyImage('Image***2');
 img1.showImage();
 img2.showImage();
    }
}

Пример прокси защиты:

  • Предположим, что компания ABC начинает новую политику, согласно которой сотрудникам теперь будет запрещен доступ в Интернет на основании их ролей. Все внешние сайты электронной почты будут заблокированы. В такой ситуации мы создаем интерфейс InternetAccess, который состоит из операции grantInternetAccess ().
  • Класс RealInternetAccess, который позволяет доступ в Интернет для всех. Однако для ограничения этого доступа мы будем использовать класс ProxyInternetAccess, который проверит роль пользователя и предоставит доступ на основе их ролей.

Диаграмма классов:

Пример защитного прокси

Пример кода:

Доступ в Интернет:

1
2
3
public interface InternetAccess {
    public void grantInternetAccess();
}

RealInternetAccess.java

01
02
03
04
05
06
07
08
09
10
11
12
13
public class RealInternetAccess implements InternetAccess {
    private String employeeName = null;
 
    public RealInternetAccess(String empName) {
        this.employeeName = empName;
    }
 
    @Override
    public void grantInternetAccess() {
        System.out.println('Internet Access granted for employee: '
                + employeeName);
    }
}

ProxyInternetAccess.java

01
02
03
04
05
06
07
08
09
10
11
12
13
public class RealInternetAccess implements InternetAccess {
    private String employeeName = null;
 
    public RealInternetAccess(String empName) {
        this.employeeName = empName;
    }
 
    @Override
    public void grantInternetAccess() {
        System.out.println('Internet Access granted for employee: '
                + employeeName);
    }
}

Client.java

1
2
3
4
public static void main(String[] args) {
        InternetAccess ia = new ProxyInternetAccess('Idiotechie');
        ia.grantInternetAccess();
    }

Выгоды:

  • Одно из преимуществ шаблона Proxy, как вы видели в приведенном выше примере, касается безопасности.
  • Этот шаблон позволяет избежать дублирования объектов, которые могут быть огромного размера и занимают много памяти. Это, в свою очередь, увеличивает производительность приложения.
  • Удаленный прокси-сервер также обеспечивает безопасность, устанавливая локальный код прокси-сервера (заглушки) на клиентском компьютере и затем обращаясь к серверу с помощью удаленного кода.

Недостатки / Последствия:

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

Интересные моменты:

  • Есть немного различий между связанными образцами. Подобно шаблону адаптера, интерфейс субъекта отличается от интерфейса, в то время как шаблоны Proxy предоставляют тот же интерфейс, что и исходный объект, но декоратор предоставляет расширенный интерфейс. Шаблон декоратора добавляет дополнительное поведение во время выполнения.
  • Прокси, используемый в Java API: java.rmi. *;

Пожалуйста, не забудьте оставить свои комментарии. Если вам понравилась эта статья, поделитесь этой статьей с друзьями через ссылки в социальных сетях.

Скачать образец кода:

Ссылка: Gang of Four — шаблон проектирования прокси от нашего партнера JCG Майнака Госвами в блоге Idiotechie .