为其他对象提供一种代理以控制对这个对象的访问
代理模式按照代理类运行前是否存在还可以分为静态代理和动态代理。
应用场景:
-
远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
-
虚拟代理,这种方式通常用于要创建的目标对象开销很大时。例如,下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
-
缓冲代理:为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。
-
保护代理:可以控制对一个对象的访问权限,为不同用户提供不同级别的使用权限。
-
安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。
-
智能指引,主要用于调用目标对象时,代理附加一些额外的处理功能。例如,增加计算真实对象的引用次数的功能,这样当该对象没有被引用时,就可以自动释放它。
-
延迟加载,指为了提高系统的性能,延迟对目标的加载。例如,Hibernate 中就存在属性的延迟加载和关联表的延时加载。
静态代理:
public interface Sourceable {
public void method();
}
public class Source implements Sourceable {
@Override
public void method() {
System.out.println("the original method!");
}
}
public class Proxy implements Sourceable {
private Source source;
public Proxy(){
super();
this.source = new Source();
}
@Override
public void method() {
before();
source.method();
atfer();
}
private void atfer() {
System.out.println("after proxy!");
}
private void before() {
System.out.println("before proxy!");
}
}
public class ProxyTest {
public static void main(String[] args) {
Sourceable source = new Proxy();
source.method();
}
}
动态代理:
// 被代理接口,定义要实现的功能。
public interface Subject {
void visit();
}
// 被代理类,完成实际的功能。
public class ConcreteSubject implements Subject {
@Override
public void visit() {
System.out.println("visit");
}
}
// 动态代理类,实现InvocationHandler接口。
public class DynamicProxy implements InvocationHandler {
private Subject mSubject;
public DynamicProxy(Subject subject) {
mSubject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("函数执行前自定义操作");
// 调用被代理类的方法时会调用该方法
method.invoke(mSubject, args);
System.out.println("函数执行后自定义操作");
return null;
}
}
public class Client {
public static void main(String[] args) {
Subject subject = new ConcreteSubject();
DynamicProxy proxy = new DynamicProxy(subject);
// 动态生成代理类
Subject proxySubject = (Subject) Proxy.newProxyInstance(DynamicProxy.class.getClassLoader()
, subject.getClass().getInterfaces()
, proxy);
proxySubject.visit();
}
}
根据以下文章总结:
-
Java设计模式:23种设计模式全面解析(超级详细)HYPERLINK http://c.biancheng.net/design_pattern/
-
设计模式 https://blog.csdn.net/shusheng0007/category_8638565.html
-
java设计模式 https://blog.csdn.net/qq_37909508/category_8976362.html
-
设计模式 https://www.cnblogs.com/zuoxiaolong/category/509144.html
-
设计模式 在源码中的应用 https://blog.csdn.net/qq_36970993/category_10620886.html
-
Android系统设计中存在设计模式分析 https://www.2cto.com/kf/201208/150650.html
-
Android设计模式系列 - 基于android的各种代码分析各种设计模式 https://www.cnblogs.com/qianxudetianxia/category/312863.html