代理模式
这一章以潘金莲和王婆以及西门庆三人的故事作为程序的对象,下面就通过西门庆与潘金莲的故事来理解代理模式,途中车速过高,各位请系好安全带,发车喽!!!
什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被代理的人能干活呀。
比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理,表现在程序上时这样的:
定义接口
这个接口我们只定义两个函数去工作,也就是把一类女人抽象出来,而这类女人能干什么事情,具体怎么干,就需要实现这个接口的类来去做
/**
* @author LeeZhi
* @version 1.0
*/
public interface KindWomen {
//这中类型的女人会做什么事呢?
public void makeEyesWithMan();//抛媚眼
public void happyWithMan(); //happy what? you know that!
}
实现类
潘金莲类
小潘实现了这个上面所定义的接口,自然也就要实现这类女人该做什么
/**
* @author LeeZhi
* @version 1.0
* 定义潘金莲是一个什么样的人
*/
public class PanJinLian implements KindWomen{
@Override
public void makeEyesWithMan() {
System.out.println("小潘在抛媚眼");
}
@Override
public void happyWithMan() {
System.out.println("小潘在和男人那个");
}
}
王婆类
这里王婆的默认构造器不写入参数,那她就是小潘的代理人,也就是被代理类,如果传入了其他的,传入谁,代理谁
这里的有参构造器后面再说,我们先看小潘的故事
/**
* @author LeeZhi
* @version 1.0
* 额,王婆什么姿色不用我多说了吧,没人会喜欢
* 但是她有经验有智慧,可以作为一类女人的代理!
*/
public class WangPo implements KindWomen{
private KindWomen kindWomen;
public WangPo() {//无参构造器,默认是潘金莲的代理
this.kindWomen = new PanJinLian();
}
//她可以是KindWomen的任何一个女人的代理,只要你是这一类型
public WangPo(KindWomen kindWomen) {
this.kindWomen = kindWomen;
}
@Override
public void makeEyesWithMan() {
this.kindWomen.makeEyesWithMan();//王婆年龄大了,谁还看她抛媚眼
}
@Override
public void happyWithMan() {
this.kindWomen.happyWithMan();//自己干不动了,让年轻的来代替自己,欸嘿嘿!??
}
}
男主角西门庆类(DeBug看实现)
水浒里是这样写的:西门庆被潘金莲用竹竿敲了一下雅道,痴迷了,
被王婆看到了,就开始撮合两人好事,王婆作为潘金莲的代理人
收了不少好处费,那我们假设一下:
如果没有王婆在中间牵线,这两个不要脸的能成吗?难说的很!
public class XiMenQing {
public static void main(String[] args) {
//把王婆叫出来
WangPo wangPo = new WangPo();
//然后西门庆就说,我要和潘金莲nappy,然后王婆就安排了西门庆丢筷子的那出戏:
wangPo.makeEyesWithMan();
wangPo.happyWithMan();//看到没,虽然表面上时王婆在做,实际上爽的是潘金莲
}
}
在这里我们追溯一下debug,看一下代理类是如何让被代理类(委托类)干活
看的出来,现在是王婆在干活哈
继续下一步时,我们可以看到了,因为王婆是潘金莲的代理人,他的无参构造器默认是潘金莲的实例化
王婆这个委托类调用的潘金莲这个类对象的相关方法,给西门庆提供特定服务
那这就是活生生的一个例子,通过代理人实现了某种目的,如果真去掉王婆这个中间环节,直接是西门庆和潘金莲勾搭,估计很难成就武松杀嫂事件。
贾氏!??
那我们再考虑一下,水浒里还有没有这类型的女人?有,卢俊义的老婆贾氏(就是和那个固管家苟合的那个),那我们也让王婆做她的代理:
public class JiaShi implements KindWomen {
@Override
public void makeEyesWithMan() {
System.out.println("贾氏抛媚眼");
}
@Override
public void happyWithMan() {
System.out.println("贾夫人正在happy中");
}
}
西门庆勾引贾氏
public static void main(String[] args) {
//把王婆叫出来
WangPo wangPo = new WangPo();
//西门庆勾引贾氏
JiaShi jiaShi = new JiaShi();
wangPo = new WangPo(jiaShi);
wangPo.makeEyesWithMan();
wangPo.happyWithMan();
}
}
不难看出,王婆还是那个王婆,内部调用的还是贾氏的方法
总结
说完这个故事,那额总结一下,代理模式主要使用了Java的多态,干活的是被代理类,代理类主要是接活,你让我干活,好,我交给幕后的类去干,你满意就成,那怎么知道被代理类能不能干呢?同根就成,大家知根知底,你能做啥,我能做啥都清楚的很,同一个接口呗。
写在后面
代理模式在Java设计中用处颇多,Java又分为静态代理和动态代理,动态代理又有很多种,例如JDK代理和CGlib代理。像我们现在主流的框架Spring里的Aop就使用了代理模式,因为博主旨在介绍什么是代理模式,让本小白理解代理模式是什么如何实现,就不会在本系列过多的讲述代理模式的应用。(说起来也是没实力去阐述明白框架里如何使用的,请轻点喷)