| 代理模式、动态代理和面向方面 
 
 代理的意思很好理解,它借鉴了我们日常所用的代理的意思:就是本来该自己亲自去做的某件事,由于某种原因不能直接做,而只能请人代替你做,这个被你请来做事的人就是代理。比如过春节要回家,由于你要上班,没时间去买票,就得票务中介代你购买,这就是一种代理模式。这个情景可以形象的描述如下:
 class:火车站
 {
 卖票:
 {……}
 }
 火车站是卖票的地方,我们假设只能在火车站买到票。卖票的动作实质是火车站类完成的。
 Class:票务中介
 {
 卖票:
 {
 收中介费;
 火车站.卖票;
 }
 }
 顾客找票务中介买票的时候,调用票务中介.卖票。票务中介其实做了两件事,一是去火车站买票,二是不能白帮你卖票,肯定要收中介费。而你得到的好处是不用直接去火车站买票,节省了买票的时间用来上班。
 以上我们简单模拟了代理模式的情景和为什么要使用代理模式,下面我们以一个例子来具体分析一下JAVA中的代理模式。
 假设有一个信息管理系统,用些用户有浏览信息的权限,有些用户有浏览、添加和修改信息的权限,还有些用户有除了上述的权限,还有删除信息的权限,那么我们最容易想到的做法如下:
 public class ViewAction
 {
 //由userId计算权限
 ……
 String permission = ……;
 if(permission.equals(Constants.VIEW))
 {
 System.out.println(“You could view the information……”);
 ……
 }
 }
 其他的动作都和浏览信息的动作差不多。我们来看这样的类,很容易看出它的一些缺点来:第一、它把权限计算和动作执行都放在一个类里,两者的功能相互混在一起,容易造成思路的混乱,而且修改维护和测试都不好;一句话来说,它不满足单一职责原则。第二是客户调用的时候依赖具体的类,造成扩展和运行期内的调用的困难,不满足依赖颠倒原则。
 既然有这么多的问题,我们有必要对该类进行重新设计。其实大家早已想到,这个类应该使用代理模式。是啊,和我们买火车票的动作一样,动作类不能直接执行那个动作,而是要先检查权限,然后才能执行;先检查权限,后执行的那各类其实就是一个代理类,修改后的代码如下:
 public interface Action
 {
 public void doAction();
 }
 首先是设计一个接口,用来满足依赖颠倒原则。
 Public class ViewAction implements Action
 {
 public void doAction()
 {
 //做View的动作
 System.out.println(“You could view the information……”);
 ……
 }
 }
 这个类跟火车站一样,是动作的真实执行者。
 Public class ProxyViewAction implements Action
 {
 private Action action = new ViewAction();
 public void doAction()
 {
 //调用权限类的方法取得用户权限
 if(Permission.getPermission(userId).equals(Constants.VIEW))
 {
 action.doAction();
 }
 }
 }
 这是代理类,很容易理解。在我们的ProxyViewAction类中,除了做了客户真正想要做的动作:doAction()以外,还进行了额外的动作检查用户的权限。而作核心动作doAction()是在一个干干净净的类:ViewAction中进行,这个类只做核心动作,对其他的不关心,满足了单一职责原则。
 客户端通过调用代理类来执行动作,而代理类一是将权限判断和动作的执行分离开来,满足了单一职责原则;二是实现了一个接口,从而满足了依赖颠倒原则。比第一个思路好了很多。
 代理又被称为委派,说的是代理类并不真正的执行那个核心动作,而是委派给另外一个类去执行,如ProxyView类中,ProxyView类并没有真正执行doAction()方法,而是交给ViewAction类去执行。
 
 
 |