1. 概述
代理模式允许我们创建一个充当另一个资源接口的中介,同时还隐藏了组件的底层复杂性。
2. 代理模式示例
考虑一个需要一些初始配置的重型Java对象(如JDBC连接或SessionFactory)。
我们只希望按需初始化此类对象,一旦初始化,我们希望在所有调用中重用它们:
现在让我们为这个对象创建一个简单的接口和配置:
public interface ExpensiveObject {
void process();
}
并且这个接口的实现有一个很大的初始配置:
public class ExpensiveObjectImpl implements ExpensiveObject {
public ExpensiveObjectImpl() {
heavyInitialConfiguration();
}
@Override
public void process() {
LOG.info("processing complete.");
}
private void heavyInitialConfiguration() {
LOG.info("Loading initial configuration...");
}
}
我们现在将利用代理模式并按需初始化我们的对象:
public class ExpensiveObjectProxy implements ExpensiveObject {
private static ExpensiveObject object;
@Override
public void process() {
if (object == null) {
object = new ExpensiveObjectImpl();
}
object.process();
}
}
每当我们的客户端调用process()方法时,他们只会看到处理过程,并且初始配置将始终保持隐藏状态:
public static void main(String[] args) {
ExpensiveObject object = new ExpensiveObjectProxy();
object.process();
object.process();
}
请注意,我们调用了process()方法两次,在幕后,设置部分只会发生一次-当对象第一次被初始化时。
对于所有其他后续调用,此模式将跳过初始配置,并且仅进行处理:
Loading initial configuration...
processing complete.
processing complete.
3. 何时使用代理
- 当我们想要一个复杂或沉重的物体的简化版本时,在这种情况下,我们可以用一个按需加载原始对象的骨架对象来表示它,也称为延迟初始化,这称为虚拟代理
- 当原始对象存在于不同的地址空间中时,我们希望在本地表示它。我们可以创建一个代理来执行所有必要的样板操作,例如创建和维护连接、编码、解码等,同时客户端访问它,因为它存在于他们的本地地址空间中,这称为远程代理
- 当我们想在原来的底层对象上增加一层安全性,以提供基于客户端访问权限的受控访问,这称为保护代理
4. 总结
在本文中,我们了解了代理设计模式,在以下情况下这是一个不错的选择:
- 当我们想要拥有对象的简化版本或更安全地访问对象时
- 当我们想要一个远程对象的本地版本时
与往常一样,本教程的完整源代码可在GitHub上获得。
Show Disqus Comments
Post Directory
扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章