代理设计模式
给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象。
代理主要可分为静态代理,动态代理和远程代理等.我们以静态代理和动态代理为例.
实现上 代理类,和真正的对象实现相同的接口,需要代理的方法是接口的方法.因此在用户调用代理类的方法,实际上通过代理类内部初始化一个代理对象,调用的代理对象的方法.
静态代理
静态代理中我们举LOL中瞎子的故事
首先创建抽象对象
/**
* 公共的接口(抽象角色)
*/
public interface Hero {
/**
* 学习技能
*/
void learnSKills();
}
然后分别创建真正的对象就是 盲僧
/**
* 真正的对象
*/
public class BlindMonk implements Zhuangshizhe.Hero {
private String name;
public BlindMonk(String name) {
this.name = name;
}
@Override
public void learnSKills() {
System.out.print(name + ":升级成功!\n");
}
}
创建代理对象 ProxyHero
/**
* 代理类
*/
public static class ProxyHero implements Hero {
BlindMonk mBlindMonk;
public ProxyHero() {
mBlindMonk = new BlindMonk("瞎子");
}
@Override
public void learnSKills() {
if (Math.random()<0.5){
mBlindMonk.learnSKills();
}else {
System.out.println("经验不够不能升级");
}
}
}
使用main 测试
/**
* 代理模式测试
*/
private static void daili() {
Hero hero=new Daili.ProxyHero();
hero.learnSKills();
}
从这个简单的例子其实可以看出 代理模式注重于对真实对象的控制, 代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行,至于具体真正的对象是在代理类中实例化还是以传参数的形式,我倒觉得这个是无所谓的,假设这个代理类可以代理多个对象我觉得外传参数也ok,如果是单个对象那么就可以在代理类中实例化.
在阎宏的java与<
动态代理
实际运用中我们大部分使用的是动态代理类,如果类方法数量越来越多的时候,代理类的代码量是十分庞大的。所以引入动态代理来解决此类问题。
代理类在程序运行时创建的代理方式被成为 动态代理。也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。
使用方法:
* 1:创建公共接口
* 2:创建委托类(真正的对象)
* 3:创建一个实现InvocationHandler 接口的调用处理器类
这个类主要是指定运行时将生成的代理类需要执行的具体任务
* 4:通过系统的代理方法newProxyInstance生成代理对象
* 5:执行方法
还是使用盲僧的例子
/**
* 公共的接口(抽象角色)
*/
public interface Hero {
/**
* 学习技能
*/
void learnSKills();
}
public static class BlindMonk implements Hero{
private String name;
public BlindMonk(String name) {
this.name = name;
}
@Override
public void learnSKills() {
System.out.print(name + ":升级成功!\n");
}
}
public static class ProxyHero implements InvocationHandler{
Hero mHero;
public ProxyHero(Hero proxy) {
this.mHero = proxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print("ProxyHero的invoke\n");
/可以类似上面静态代理一样控制被代理对象的方法是否执行
Object invoke = method.invoke(mHero, args);
return invoke;
}
}
public static void main(String[] args) {
BlindMonk monk=new BlindMonk("盲僧");//委托对象(真正的对象)
ProxyHero handler = new ProxyHero(monk); //2.创建调用处理器对象
Hero proxy = (Hero) Proxy.newProxyInstance(monk.getClass().getClassLoader(),
monk.getClass().getInterfaces(), handler);//创建代理对象
proxy.learnSKills();
}