分为静态代理和动态代理,静态代理就是自己写相应的代理类和实现,动态代理就是用JDK自带的机制,jdk会在运行中动态的生成代理类;
在例子中具体买房等方法理解成子类中介怎么去做,可以有很多的中介。而真正的代理类更像是如链家那个房子。去指派哪些人,分配哪些人去完成工作。其实用的依旧是java中最常见的继承、多态的关系。
转:https://www.jianshu.com/p/2fedb6bad7f9
1、静态代理
静态代理很好理解就是我们需要编写一个代理类。实现我们需要代理的所有方法。所以称之为静态代理。由于需要代理的方法可能有很多。为了约束代理类和被代理类这些相同的方法,所以写一个接口来继承是最直观的方式,当然这个接口不是必须的,可加可不加。都不影响,主要是理解代理这个设计模式的思想。代理模式的变化也很多。
public interface ProxyInterface {
void choiceBetterHouse(); //模拟挑选优质房子
void buyHouse(); //模拟买房子
}
然后我们定义一个叫Petter的人
public class Petter implements ProxyInterface {
private static final String TAG = Petter.class.getSimpleName();
@Override
public void choiceBetterHouse() {
Log.d(TAG,"挑选优质房子");
}
@Override
public void buyHouse() {
Log.d(TAG,"买房子");
}
}
然后定义代理类
public class StaticProxy implements ProxyInterface {
private Petter petter;
public StaticProxy(Petter petter) {
this.petter = petter;
}
@Override
public void choiceBetterHouse() {
petter.choiceBetterHouse();
}
@Override
public void buyHouse() {
petter.buyHouse();
}
}
然后就是调用
Petter petter = new Petter();
StaticProxy agency = new StaticProxy(petter);
agency.choiceBetterHouse();
agency.buyHouse();
输出这里就不打印了。静态代理就是这么简单。就是代理petter挑选优质房子,买房子。卖家接触的都是中介,真正执行和做决定的是Petter。现实代码中我们见得多的也就是这种代理了。
2、动态代理
动态代理和静态代理的区别就是动态代理不用我们去手动编写代理类。动态代理就是JDK提供的机制,可在内存中动态的生成代理类。
例子还是上面的例子,我们重新编写动态代理类
public class DynamicProxy implements InvocationHandler {
private static final String TAG = DynamicProxy.class.getSimpleName();
private Object object;
public DynamicProxy(Object object) {
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Log.d(TAG,"invoke");
Object result = method.invoke(object,args);
return result;
}
}
动态代理的核心就是继承InvocationHandler这个接口,通过method的invoke方法来间接调用原本的方法。这里和java反射调用方法的时候一样。
然后我们看客户端是如何调用的
Petter petter = new Petter();
// 返回一个代理对象
ProxyInterface proxyPetter = (ProxyInterface) Proxy.newProxyInstance(
petter.getClass().getClassLoader(),
petter.getClass().getInterfaces(),
new DynamicProxy(petter));
proxyPetter.choiceBetterHouse();
proxyPetter.buyHouse();
这里就是最关键的一步了,Proxy.newProxyInstance来生成一个代理对象。通过这个代理对象就可以调用需要被代理的方法了。我们来看输出
01-23 11:40:14.169 18725-18725/com.yink.designpattern.designpattern D/DynamicProxy: invoke
01-23 11:40:14.169 18725-18725/com.yink.designpattern.designpattern D/Petter: 挑选优质房子
01-23 11:40:14.169 18725-18725/com.yink.designpattern.designpattern D/DynamicProxy: invoke
01-23 11:40:14.169 18725-18725/com.yink.designpattern.designpattern D/Petter: 买房子
好了,动态代理模式就这点儿东西了。比较的时候,注意对比StaticProxy、DynamicProxy的代码就可以了。
作者:Yink_Liu
链接:https://www.jianshu.com/p/2fedb6bad7f9
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。