设计模式-代理
2020-04-14 本文已影响0人
isLJli
代理设计模式 定义:
为其他对象提供一种代理,以控制对这个对象的访问,分为静态代理和动态代理。
分为:
- 目标接口
- 代理对象 (实现目标接口)
- 被代理的对象 (实现目标接口)
静态代理
其实就是代理对象,通过构造方法的参数拿到被代理对象的值,在执行相关接口的方法时,真正执行的是被代理对象的方法。
代码示例:
目标接口:
public interface IBank {
/**
* 办卡
*/
void applyBank();
}
代理对象:
public class BankWork implements IBank {
private IBank iBank;
/**
* 持有被代理的对象
* @param bank
*/
public BankWork(IBank bank){
this.iBank=bank;
}
//真正执行的是被代理对象的方法
@Override
public void applyBank() {
System.out.println("开始受理");
iBank.applyBank();
System.out.println("操作完毕");
}
}
被代理对象:
public class Man implements IBank{
private String name;
public Man(String name){
this.name=name;
}
@Override
public void applyBank() {
System.out.println(name+"申请办卡");
}
}
通过代理对象调用方法:
public class Client {
public static void main(String[] args){
Man man=new Man("DaMing");
BankWork bankWork = new BankWork(man);
bankWork.applyBank();
}
}
结果:
开始受理
DaMing申请办卡
操作完毕
静态代理的优缺点:
静态代理虽然简单,但是如果我们的目标接口增加/删除接口时,我们的代理对象也要跟着增加和删除相应的实现方法,比较麻烦。在java中为我们提供了一种动态代理对象,可以帮我们生成代理对象,使得我们不必关心代理对象的方法实现:
动态代理
动态代理,帮我们实现了代理对象,使得我们不必关心接口方法的增加删除,其中最重要的是一个invocationHandler类中的invoke()方法。
增加一个接口方法
public interface IBank {
/**
* 办卡
*/
void applyBank();
/**
* 额外业务
*/
void extraBank();
}
在被代理对象中增加相应的操作:
public class Man implements IBank {
private String name;
public Man(String name){
this.name=name;
}
@Override
public void applyBank() {
System.out.println(name+"申请办卡");
}
@Override
public void extraBank() {
System.out.println(name+"额外业务");
}
}
通过Proxy生成我们的代理对象,对在invocationHandler的invote()方法中
public class BaseInvocationHandler implements InvocationHandler {
/**
* 被代理的对象
*/
private Object mobject;
public BaseInvocationHandler(Object object){
this.mobject=object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行方法-目标接口调用的方法,都会来到这里面
// System.out.println("name="+method.getName());
System.out.println("开始受理");
//调用被代理对象的相关方法(method)
Object object = method.invoke(mobject,args);
System.out.println("操作完毕");
return object;
}
}
public class Client {
public static void main(String[] args){
com.ljli.myapplication.proxy.simple2.Man man=new Man("DaMing");
IBank bank=(com.ljli.myapplication.proxy.simple2.IBank) Proxy.newProxyInstance(
//返回接口的实例,这个对象式
com.ljli.myapplication.proxy.simple2.IBank.class.getClassLoader(), //ClassLoader
new Class[]{com.ljli.myapplication.proxy.simple2.IBank.class}, // 目标接口
new BaseInvocationHandler(man)
);
//当调用这个方法时,会来到BaseInvocationHandler的invode方法
bank.applyBank();
bank.extraBank();
}
}
输出结果:
开始受理
DaMing申请办卡
操作完毕
开始受理
DaMing额外业务
操作完毕
使用代理模式的应用有:
- Android 插件化架构之绕过 AndroidManifest 检测(动态代理)
- Android 数据库实现数据的懒加载(静态代理)
- Android MVP 架构设计(静态代理和动态代理)
- Android Xutils 实现 View 事件注入(动态代理)
- Android Retrofit 的 create 创建接口对象 (动态代理)
- Android Framework 层的 AMS
- Android Framework 层的 Binder 驱动