代理模式又分为静态代理和动态代理。
静态代理
静态代理的代理类和目标类都是死的,下面是一个静态代理的小例子,
先创建Timo类,可以看到,timo想要五杀,
/**
* timo类
* */
public class TiMo {
public void wantPentaKill() {
System.out.println("Timo想要五杀");
}
}
我创建一个代打类,来帮助Timo拿到五杀,
/**
* 代打类
* */
public class DaiDa {
private TiMo tiMo;
public DaiDa(TiMo tiMo) {
this.tiMo = tiMo;
}
public void wantPentaKill() {
System.out.println("代打开始操作啦..");
tiMo.wantPentaKill();
System.out.println("提莫拿到了五杀");
}
}
测试,
public class Test {
public static void main(String[] args) {
DaiDa daiDa = new DaiDa(new TiMo());
daiDa.wantPentaKill();
}
}
运行结果:
代打开始操作啦..
Timo想要五杀
提莫拿到了五杀
总结
可以看到代打帮助timo拿到了五杀,但是缺点也比较明显,这个代打只会timo,不会其他的英雄。
动态代理
我们使用动态代理来改进我们的代打类,使其可以会所有英雄。
创建Hero接口,
/**
* 英雄接口
* */
public interface Hero {
void wantPentaKill();
}
这里我们使用jdk的动态代理来实现,
Proxy.newProxyInstance()
需要三个参数,ClassLoader类加载器,Interfaces接口数组,this就是实现了InvocationHandler接口的对象,这里就是SuperDaiDa 类本身了,所有传入的是this,我们的目标方法需要在实现了InvocationHandler接口的类中的invoke方法中执行。
public class SuperDaiDa implements InvocationHandler {
private Hero hero;
public Hero getInstance(Hero hero) {
this.hero = hero;
Class<?> clazz = hero.getClass();
return (Hero) Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("超级代打开始操作了...");
Object result = method.invoke(this.hero, args);
System.out.println("拿到五杀");
return result;
}
}
测试:
创建Yasuo类并实现Hero接口,让SuperDaiDa来代理我们刚创建的类。
/**
* 只要是一个英雄,并且想要五杀
* */
public class YaSuo implements Hero {
@Override
public void wantPentaKill() {
System.out.println("YaSuo想要五杀");
}
}
public class Test {
public static void main(String[] args) {
SuperDaiDa superDaiDa = new SuperDaiDa();
Hero yasuo = superDaiDa.getInstance(new YaSuo());
yasuo.wantPentaKill();
}
}
运行结果:
超级代打开始操作了...
YaSuo想要五杀
拿到五杀
总结
动态代理在运行生成要被代理的对象,上面里Hero只有一个wantPentaKill的方法,如果我们想要更多的方法,直接添加就行了,在接口中追加即可。
版权声明:本文为m0_46130323原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。