Ранее мы использовали шаблон фасада для взаимодействия с унаследованным приложением. Наш следующий шаблон будет шаблон прокси.
Шаблон прокси используется, когда мы хотим
- Контролировать доступ к объекту
- Добавить дополнительную функциональность при доступе к объекту.
Одно из самых распространенных применений — это когда мы хотим отслеживать конкретные действия и добавлять некоторые показатели.
Например, у нас есть служба загрузки данных.
|
1
2
3
4
5
6
7
|
package com.gkatzioura.design.structural.proxy;public interface DataUploadService { void upload(String payload);} |
И его реализация http
|
01
02
03
04
05
06
07
08
09
10
|
package com.gkatzioura.design.structural.proxy;public class HttpDataUploadImpl implements DataUploadService { @Override public void upload(String payload) { }} |
Нам необходимо принять некоторые меры в среднем времени, необходимом для отправки полезной нагрузки нашего приложения, чтобы решить, достаточно ли хороша наша реализация. Если нет, возможно, нам нужно рассмотреть что-то более производительное.
Вместо того, чтобы возиться с нашей реализацией и добавлять код, который не имеет ничего общего с фактической передачей полезной нагрузки, мы создадим прокси нашей реализации.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package com.gkatzioura.design.structural.proxy;import java.nio.charset.Charset;import java.time.Duration;import java.time.Instant;public class HttpDataUploadProxy implements DataUploadService { private final HttpDataUploadImpl httpDataUpload; public HttpDataUploadProxy(HttpDataUploadImpl httpDataUpload) { this.httpDataUpload = httpDataUpload; } @Override public void upload(String payload) { Instant start = Instant.now(); httpDataUpload.upload(payload); Duration duration = Duration.between(start,Instant.now()); int byteSize = payload.getBytes(Charset.defaultCharset()).length; /** * Log properly to splunk, cloudwatch etc */ }} |
Как вы видите, наша реализация не изменилась, и нам удается отправить метрики, необходимые для выбранной вами аналитической службы.
Мы также можем применить тот же шаблон в случае, если эта служба имеет некоторую квоту, и поэтому мы хотим контролировать ее, потому что это может привести к превышению бюджета.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.gkatzioura.design.structural.proxy;public class HttpDataUploadQuotaProxy implements DataUploadService { private final HttpDataUploadImpl httpDataUpload; public HttpDataUploadQuotaProxy(HttpDataUploadImpl httpDataUpload) { this.httpDataUpload = httpDataUpload; } @Override public void upload(String payload) { if(quotaExceeded()) { throw new IllegalStateException("Quota exceeded cannot upload payload"); } httpDataUpload.upload(payload); } private boolean quotaExceeded() { /** * Code that should check whether we exceeded our quota or not */ return false; }} |
Подводя итог, мы просто использовали шаблон прокси для управления доступом к нашему объекту, а также для улучшения его функциональности.
Вы также можете найти исходный код на github .
| Опубликовано на Java Code Geeks с разрешения Эммануила Гкациоураса, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Структурные шаблоны проектирования: Proxy Pattern
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |