菏泽建设职业中等专业学校官方网站,去掉域名后的wordpress,珠宝购物网站的建设,中国十大咨询管理公司大家好#x1f44b;#xff0c;我是极客涛#x1f60e;#xff0c;今天我们聊一聊java中的代理模式#xff0c;话不多说#xff0c;还是老思路#xff0c;什么是代理模式#xff0c;为什么要有代理模式#xff0c;如何实现代理模式 代理模式
在说java中的代理模式之前… 大家好我是极客涛今天我们聊一聊java中的代理模式话不多说还是老思路什么是代理模式为什么要有代理模式如何实现代理模式 代理模式
在说java中的代理模式之前我们可以先想一想生活的例子这里也是一个加深自己对程序设计理解的一种学习方式程序本质上就是对生活的抽象和实现。
生活中的代理模式太多了
我想租房不需要自己去网上搜找个中介把需求讲清楚房子就找好了我想吃饭点个外卖外卖员就送上门了我就可以直接吃了不用自己去拿
这里如果我们进行抽象的话对于租房来说我本身只有判断房子适不适合我的能力但是我没有不想对房源进行检索的能力这时候中介其实就是代理了我对房源进行检索但最终房子适不适合还是我自己决定对点外卖来说我不想自己去店里拿所以外卖小哥代理了我帮把饭送到我手上我自己用吃的能力。
也就是说代理模式的核心就是对被代理对象的能力拓展。
代理方式
静态代理
我们拿我吃饭的场景举例说明
定义一个Person接口有吃的能力定义实现类GeekTao代表我自己实现了吃的能力定义实现类Taker代表外卖员外卖员除了有吃的能力自己还有送外卖的专属能力
/*** 人*/
public interface Person {/*** 吃*/void eat();
}/*** 我*/
public class GeekTao implements Person {Overridepublic void eat() {System.out.println(我自己吃饭);}
}/*** 外卖员*/
public class Taker implements Person {private final Person me;public Taker() {me new GeekTao();}Overridepublic void eat() {// 送外卖this.send();// 吃饭me.eat();}private void send() {System.out.println(外卖员把外卖送到家);}
}测试方法
public class ProxyTest {public static void main(String[] args) {Person taker new Taker();taker.eat();}
}运行结果
外卖员把外卖送到家
我自己吃饭真好现在可以不用自己去拿外卖外卖小哥就把外卖送到了还有个问题吃完我又口渴了如果我还想喝抽象一个drink方法外卖小哥是不是还得实现一个drink方法下边做个简单示例。
/*** 外卖员*/
public class Taker implements Person {private final Person me;public Taker() {me new GeekTao();}Overridepublic void eat() {// 送外卖this.send();// 吃饭me.eat();}private void send() {System.out.println(外卖员把外卖送到家);}Overridepublic void drink() {// 送外卖this.send();// 喝水me.drink();}
}以上实现其实就是静态代理核心在于“静态”对于我来说外卖小哥要实现一次除了我还有很多人也需要点外卖那外卖小哥每个都要适配一次每次我自己有了新的需求方法外卖小哥也要跟着实现但其实对于他来说实现方法都一样都是送外卖所以这也是静态代理的缺点非常不灵活。
动态代理
还是拿我吃饭的场景举例子上边说到外卖小哥不只是给我送外卖那如何实现一个小哥可以给不同的人送外卖呢
定义一个Person接口有吃的能力定义实现类GeekTao代表我自己实现了吃的能力定义实现类XiaoMing也实现了吃的能力也需要点外卖定义实现类TakerCommon代表外卖员外卖员除了有吃的能力自己还有送外卖的专属能力并且不只是可以给我送外卖还可以给其他人送
其它类和上边例子一样只贴了TakerCommon。
/*** 通用外卖员*/
public class TakerCommon implements InvocationHandler {private Object proxyTarget;public Object sendWho(Object target) {this.proxyTarget target;return Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(), proxyTarget.getClass().getInterfaces(), this);}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(外卖员送外卖给 proxyTarget.getClass().getSimpleName());return method.invoke(proxyTarget, args);}
}测试方法
public class ProxyTest {public static void main(String[] args) {TakerCommon takerCommon new TakerCommon();Person me (Person) takerCommon.sendWho(new GeekTao());me.eat();System.out.println();Person xiaoming (Person) takerCommon.sendWho(new XiaoMing());xiaoming.eat();}
}测试结果
外卖员送外卖给 GeekTao
我自己吃饭外卖员送外卖给 XiaoMing
小明吃饭这时候我又想喝那直接调用drink方法就行了因为对于外卖小哥来说都是一样的。
测试方法
public class ProxyTest {public static void main(String[] args) {TakerCommon takerCommon new TakerCommon();Person me (Person) takerCommon.sendWho(new GeekTao());me.eat();me.drink();System.out.println();Person xiaoming (Person) takerCommon.sendWho(new XiaoMing());xiaoming.eat();xiaoming.drink();}
}测试结果
外卖员送外卖给 GeekTao
我自己吃饭
外卖员送外卖给 GeekTao
我自己喝外卖员送外卖给 XiaoMing
小明吃饭
外卖员送外卖给 XiaoMing
小明在喝总结
代理模式的核心就是对被代理对象的能力拓展
静态代理适合简单业务不经常变动因为实现逻辑简单开发成本低
动态代理适合变动可能性较大的业务。