2003年盛大网络推出了一块风靡一时的游戏---传奇世界,在全国上下的网吧到处可见通宵达旦的“打怪达人”,小时候去网吧看着那些大孩子坐在那里,一桶泡面,一玩就是一天,想想童年的乐趣还真是简单~但是,要想获得游戏的快感,也是要付出代价的,腰酸背痛,眼睛干涩,手臂发麻等等,太难受了...这时候一种新的职业诞生了---游戏代练
简单点说就是花钱找人替你升级,这下就释放出你自己的身体了,你可以快乐的打篮球,和女同学写写情书咯!同时也引出本文的核心---代理
废话少说,下面我们直奔重点
代理模式:为其他对象提供一种代理,以控制对该对象的访问,代理模式是一种设计技巧,其他的设计模式如策略模式就是由代理模式的一种转变
下面我们来看静态代理和动态代理
静态代理:自己动手写代理类的就是静态代理
动态代理:与静态代理的概念正好相反,不许要我们动手写代理类,而是在程序运行期间,动态生成一个代理对象
下面我们以静态代理为例实现上面讲的打游戏的案例
类图:
Subject:一个普通的业务接口,无特殊要求
RealSubject:具体的业务接口,被代理人
Proxy:代理类,负责对RealSubject的行为的应用,同时也可以在RealSubject行为的前后,做前置处理或后置处理
下面我们以上面打游戏为例来看一下代理模式
首先有一个Subject,这里为IGamePlayer接口
然后需要一个RealSubject实现Subject接口
最后还需要一个代理类
测试类
运行结果
动态代理
实现阶段不用关心代理谁,而在运行阶段才去指定被代理对象,增加一个GamePalyIH类,作用就是产生一个对象的代理对象,其中InvocationHadnler是JDK的动态代理,其中invoke方法完成真实方法的调用,通过和静态代理对比可以看到,我们并没有指定创建类似GamePlayerProxy的代理类,再注入一个IGamePlayer的接口,来规范代理类所能代理的对象;相反的是,在程序运行时通过Proxy.newProxyInstance方法动态创建了一个代理对象;
关于扩展性,如果GamePlayer想在登录他的账号时得到通知,以防盗号,那么修改GamePlayer类?不需要,交给代理就好了,修改后如下图:
测试类
运行结果
注意:使用JDK动态代理的前提是,被代理的类必须要实现一个接口(从Proxy.newProxyInstance方法的第二个参数其实也可以看出,人家就这么规定的别抬杠奥!)