代理对象或代理对象为另一个对象提供占位符,以控制对该对象的访问。 代理充当原始对象的轻量级版本或简化版本。 它支持与原始对象相同的操作,但可以将那些请求委托给原始对象以实现它们。
代理设计模式是一种结构模式,其中代理类包装了实际的主题类。 客户代码仅与代理类交互,而不与真实主题交互。
在本教程中,我们将学习如何实现代理设计模式。
为什么要使用代理?
在三种最常见的情况下,我们可能需要代理类:
- 虚拟代理:当主题实例化需要大量资源时,我们可以选择使用此模式。 我们在此处创建的代理类称为虚拟代理。 一些示例用例将包括在网页上加载非常高分辨率的图像。 想法是将昂贵的资源的创建延迟到需要的时间为止
- 保护代理:我们还可以使用代理类来控制对真实主题类的访问。 例如,允许用户根据其特定用户角色访问网站
- 远程代理:此实现的真实示例是Google Docs。 Web浏览器将代理对象保存在本地,然后与远程服务器上的对象同步
UML图:
代理设计模式包含以下组件:
- 主题:定义实际主题合同的接口
- RealSubject :这是我们要为其提供代理的类
- 代理:这是真实主题的代理类。 Proxy和RealSubject类均实现Subject接口
- 客户端 :通过Subject接口与代理交互的类
Proxy和RealSubject类均实现Subject接口。 同样,客户端与Subject界面进行交互,因此它隐藏了客户端与代理进行交互而不是真实主题的事实。
代理类包装实际主题,并且可以将一些请求委托给真实主题。 但是,并非所有请求都委托给Subject类。 代理能够处理一些较轻的职责。
示例实现:
大多数组织在其场所内提供受限的Internet访问权限。 那么,如何实施呢?
这个想法是创建一个保护代理。
让我们先定义一个WebServer接口:
public interface WebServer { void makeRequest(String url); }
在这里, makeRequest()方法负责使用特定端点对Web服务器进行调用。
现在,让我们实现RealWebServer类,该类完成通过网络API调用命中URL的实际工作:
public class RealWebServer implements WebServer { @Override public void makeRequest(String url) { //code to hit a particular url } }
最后,我们将创建一个代理服务器并将其公开给我们的客户:
public class ProxyServer implements WebServer { private RealWebServer realServer; private List<String> blockedSites = new ArrayList<>(); public ProxyWebServer() { this .realServer = new RealWebServer(); } RealWebServer(); } public void blockWebsite(String url) { this .blockedSites.add(url); } @Override public void makeRequest(String url) { if (!blockedSites.contains(url)) { this .realServer.makeRequest(url); } else { System.out.println( "This website is blocked. Contact your administrator" ); } } }
这样一来,所有被阻止的网站将在场所内不可用:
//code in main method WebServer server = new ProxyWebServer(); server.blockWebsite( "www.facebook.com" ); ... server.makeRequest( "www.facebook.com" ); // Prints 'This website is blocked. Contact your administrator'
结论:
在本教程中,我们探讨了代理设计模式。
代理模式使我们可以推迟创建昂贵的资源,直到需要它为止,控制对真实主题的访问或在本地表示远程对象。
Java Reflection API依赖于代理。 同样,Hibernate的惰性获取逻辑在内部使用了这种模式。
翻译自: https://www.javacodegeeks.com/2019/09/proxy-design-pattern-java.html