代理模式
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.
这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法
举个例子来说明代理的作用:假设我们想邀请一位明星,那么并不是直接连接明星,而是联系明星的经纪人,来达到同样的目的.明星就是一个目标对象,他只要负责活动中的节目,而其他琐碎的事情就交给他的代理人(经纪人)来解决.这就是代理思想在现实中的一个例子。
代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象。
第一种:静态代理
例子:雷子是一名歌手,他只会唱歌,他唱歌之前需要宣传,所以他请了个经纪人。【/PostGetEncod/it.casyt.proxy_ststic.demo】
1.我们把歌手身份设计为一个接口:Singer
/**
* 这是代理模式的接口:
* 我们定义为一个歌手,它的方法是唱歌
*/
public interface Singer {
void sing();
}
2.雷子是一个歌手,他实现了Singer接口:LeiZi_singer
public class LeiZi_singer implements Singer{
public void sing() {
// TODO Auto-generated method stub
System.out.println("成都。。。");
}
}
3.经纪人只会给歌手做宣传,他也实现了Singer接口:Agent_ststic
/**
*【静态代理】 :雷子请了个经纪人,唱歌之前,给他打广告宣传
*/
public class Agent_ststic implements Singer{
//内部封装了雷子的对象
private LeiZi_singer leiZi_singer;
public Agent_ststic(LeiZi_singer leiZi_singer) {
super();
this.leiZi_singer = leiZi_singer;
}
//宣传方法
public void adverse() {
System.out.println("雷子要唱歌了,快来看。。。");
}
public void sing() {
// TODO Auto-generated method stub
adverse();
leiZi_singer.sing();
}
}
测试:Test_ststic_pro
public class Test_ststic_pro {
public static void main(String[] args) {
// 将雷子的对象传进去
Singer singer=new Agent_ststic(new LeiZi_singer());
singer.sing();
}
}
结果:
第二种:透明代理
雷子觉得经纪人干的不错,让他很火,所以就让经纪人只能给他代理。
在经纪人的构造函数中直接创建雷子的对象实体
public class Agent_gene implements Singer{
//内部封装了雷子的对象
private LeiZi_singer leiZi_singer;
public Agent_gene() {
super();
this.leiZi_singer=new LeiZi_singer();
}
//宣传方法
public void adverse() {
System.out.println("雷子要唱歌了,快来看。。。");
}
public void sing() {
// TODO Auto-generated method stub
adverse();
leiZi_singer.sing();
}
}
测试:
public class Test_gene_pro {
public static void main(String[] args) {
Singer singer=new Agent_gene();
singer.sing();
}
}
结果同上,却别是外界并不知道雷子,只知道经纪人,雷子成了透明的。
第三种:动态代理
经纪人不好好干,雷子决定不要这个经纪人了,换个流动的,唱歌之前就找个经纪人,不唱歌就不需要经纪人。
public class Test_mobile_pro {
public static void main(String[] args) {
final Singer singer=new LeiZi_singer();
Singer agent_singer = (Singer) Proxy.newProxyInstance(Test_mobile_pro.class.getClassLoader(), singer.getClass().getInterfaces(),new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equalsIgnoreCase("sing")) {
System.out.println("雷子唱歌了,快来看哪,好好听。。。");
return method.invoke(singer, args);
}
return method.invoke(singer, args);
}
});
agent_singer.sing();
}
}
结果: