首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

署理模式的运用

2012-11-10 
代理模式的运用考虑这样一种情况。某个系统要根据用户的权限来判断是否能操作。那么可以这么写:class ViewAc

代理模式的运用

考虑这样一种情况。某个系统要根据用户的权限来判断是否能操作。那么可以这么写:

class ViewAction{String permission;public ViewAction(String permission ){this.permission = permission;}public void DoAction(){if(permission.equals("VIEW")){System.out.println("查看信息!");}}}class AddAction{String permission;public AddAction(String permission ){this.permission = permission;}public void DoAction(){if(permission.equals("ADD")){System.out.println("添加信息!");}}}public class proxy {public static void main(String[] args){//赋予用户查看权限String permission = "VIEW";ViewAction user = new ViewAction(permission);user.DoAction();AddAction user1 = new AddAction(permission);user1.DoAction();  }}

?可以看到,虽然执行了添加 查看操作,可是最后只执行了查看操作。

?

但是这样子将权限和操作放在一起,违反了类的单一性原则。不利用程序维护。

?

既然有这么多的问题,我们有必要对该类进行重新设计。其实大家早已想到,这个类应该使用代理模式。和我们买火车票的动作一样,动作类不能直接执行那个动作,而是要先检查权限,然后才能执行;先检查权限,后执行的那各类其实就是一个代理类,修改后的代码如下:

?

interface Action{public void DoAction();}class ViewAction implements Action{public void DoAction(){System.out.println("查看信息!");}}class AddAction implements Action{public void DoAction(){System.out.println("添加信息!");}}class ProxyViewAction implements Action {private Action action = null;private User user = new User() ;public ProxyViewAction(Action act) {action = act;}public void DoAction() {// 调用权限类的方法取得用户权限if (user.getPermission().equals("VIEW")) {action.DoAction();}}}//用户信息class User{private String permission = "VIEW" ;public String getPermission() {return permission;}public void setPermission(String permission) {this.permission = permission;}}public class proxy {public static void main(String[] args){ProxyViewAction proxy = new ProxyViewAction(new ViewAction());proxy.DoAction();//将用户信息的权限变成ADD,则上面的方法不能执行。  }}

?在我们的ProxyViewAction类中,除了做了客户真正想要做的动作:DoAction()以外,还进行了额外的动作检查用户的权限。而作核心动作DoAction()是在一个干干净净的类:ViewAction中进行,这个类只做核心动作,对其他的不关心,满足了单一职责原则。

?

客户端通过调用代理类来执行动作,而代理类一是将权限判断和动作的执行分离开来,满足了单一职责原则

?

代理又被称为委派,说的是代理类并不真正的执行那个核心动作,而是委派给另外一个类去执行,如ProxyView类中,ProxyView类并没有真正执行doAction()方法,而是交给ViewAction类去执行。

?

我们再来看代理类ProxyViewAction,可以看到它不仅依赖于接口Action,而且依赖于具体的实现ViewAction。这样对我们的系统扩展很不利,比如我们有Add动作、Delete动作、Modify动作等等,我们需要对每一个动作都写一个代理类,而这些代理类都做同样的事情,先进行权限判断,然后再委派。所以我们需要对这些代理再进行一次抽象,让它只依赖接口Action,而不依赖于具体的实现。??? 要实现这样的想法,我们需要将代理类中的具体实现提走,让代理的使用者在运行期提供具体的实现类,即所谓的依赖注入,代码如下

interface Action{public void DoAction();}class ViewAction implements Action{public void DoAction(){System.out.println("查看信息!");}}class AddAction implements Action{public void DoAction(){System.out.println("添加信息!");}}class ProxyAction implements Action {private Action action = null;private User user = new User() ;public ProxyAction(Action act) {action = act;}public void DoAction() {// 调用权限类的方法取得用户权限if (user.getPermission().equals(action.getClass().getSimpleName())) {action.DoAction();}}}//用户信息class User{private String permission = "ViewAction" ;public String getPermission() {return permission;}public void setPermission(String permission) {this.permission = permission;}}public class proxy {public static void main(String[] args){Action action = new ProxyAction(new ViewAction());action.DoAction();//将用户信息的权限变成AddView,则上面的方法不能执行。  }}

?这样,我们就将所有实现了Action接口的实现使用一个代理类来代理它们。除了ViewAction类能用,以后扩展的AddAction、?????? ModifyAction、DeleteAction类等等,都可以使用一个代理类:ProxyAction。

?

??? 而我们的客户端类似如下:Action action = new ProxyAction(new ViewAction());action.DoAction();
??? 通过对代理类的依赖注入,我们使得代理类初步有了一定扩展性。但是我们还要看到,这个代理类依赖于某一个确定的接口。这仍然不能满足我们的实际要求,如我们的系统的权限控制一般是整个系统级的,这样系统级的权限控制,我们很难在整个系统里抽象出一个统一的接口,可能会有多个接口,按照上面的代理模式,我们需要对每一个接口写一个代理类,同样,这些类的功能都是一样的。这显然不是一个好地解决办法。
??? 基于上面的原因,我们需要解决一个系统在没有统一的接口的情况下,对一些零散的对象的某一些动作使用代理模式的问题。JAVA API为我们引入了动态代理或动态委派的技术。
???

热点排行