我和春天有个约会(三)

  
小亮同志的疑惑,权限判断代码蛮横地渗透进纯洁的业务逻辑之中,有什么好办法让权限判断走远点呢?
AOP 前传——代理机制
距离产生美……
将logging/Security等周边逻辑等巧妙地分离出主体业务逻辑,一方面让对象责任明确各司其职,提高可维护性;另一方面让它们召之即来挥之即去,修改更加方便。自然先想到Java I/O惯用的Decorate模式。人家早就总结了,叫做“静态代理”,并在此基础上推出了“动态代理”。
要是真用Decorate(静态代理)做权限判断,那乐子可就大了。假设我有五个class,每个class平均有五个函数需要获得相应权限才能进入,那么我就要做五个interface,每个interface平均五个接口函数对应那些函数,另外我需要五个proxy class,这些proxy class要定义对上述每个函数的权限判断包装。Wow,大大不妙,如黑土大叔对白云大妈的抱怨,距离有了,美没了。
而对于Java I/O,接口函数位于底层jdk中,被各种业务逻辑反复调用,且无外乎read/readln/write/writeln等,用Decorate还是值得的。
把目光转向动态代理。首先定义权限控制类RightsSet,每当用户进入系统就会创建该类对象以标示权限:
public   class  RightsSet  {
    
public static final int NO_RIGHT = -1;
    
public static final int LOW_RIGHT = 0;
    
public static final int HIGH_RIGHT = 1;
    
    
private String name = "hezh";
    
private int right = LOW_RIGHT;
    
public RightsSet(String name, int x) {
        
this.name = name;
        
if(x < 5{
            right 
= NO_RIGHT;
        }
 else if(x >= 5 && x < 10){
            right 
= LOW_RIGHT;
        }
 else {
            right 
= HIGH_RIGHT;
        }

    }

    
    
public boolean isHighRight() {
        
return (right == HIGH_RIGHT);
    }

    
    
public boolean isLowRight() {
        
return (right == LOW_RIGHT);
    }

    
    
public String getName() {
        
return name;
    }

}

 
权限定义了三个级别:no-right/low-right/high-right;
业务逻辑的接口IMyBiz:
public   interface  IMyBiz  {
    
public void biz_no_right();
    
public void biz_low_right();
    
public void biz_hight_right();
    
public void biz_no_right1();
    
public void biz_low_right1();
    
public void biz_hight_right1();
}

 
函数名暗含了三种权限,分别为:均可进入/低权限即可进入/高权限方可进入,实现它的业务逻辑如下:
public   class  MyBiz  implements  IMyBiz  {
    
    
public void biz_no_right() {
        System.out.println(
"Any one here");
    }

    
    
public void biz_low_right() {
        System.out.println(
"Some one with low rights here");
    }

    
    
public void biz_hight_right() {
        System.out.println(
"Some one with hight here");
    }

    
    
public void biz_no_right1() {
        System.out.println(
"Any one here 111");
    }

    
    
public void biz_low_right1() {
        System.out.println(
"Some one with low rights here 111");
    }

    
    
public void biz_hight_right1() {
        System.out.println(
"Some one with hight here 111");
    }

}

 
花样在动态代理类中,每当遇到难题,java反射机制总是冲过来排忧解难,这次也不例外。jdk早就在反射中留好了动态代理接口InvocationHandler,我们实现它即可:
public   class  RightHandler  implements  InvocationHandler  {
    
private RightsSet rights_set = null;

    
private Object delegate = null;

    
public Object bind(Object delegate, RightsSet rights_set) {
        
this.rights_set = rights_set;
        
this.delegate = delegate;
        
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
                delegate.getClass().getInterfaces(), 
this);
    }


    
public Object invoke(Object proxy, Method method, Object[] args)
            
throws Throwable {
        Object result 
= null;
        String[] low_right_methods 
= "biz_low_right""biz_low_right1" };
        String[] no_right_methods 
= "biz_no_right""biz_no_right1" };
        String[] high_right_methods 
= "biz_hight_right""biz_hight_right1" };
        String method_name 
= method.getName();

        
for (int i = 0; i < low_right_methods.length; i++{
            
if (method_name.equals(low_right_methods[i])) {
                
if (rights_set.isLowRight() || rights_set.isHighRight()) {
                    result 
= method.invoke(delegate, args);
                }
 else {
                    System.out.println(rights_set.getName() 
+ "对函数"
                            
+ method_name + "权限不够");
                }

                
return result;
            }

        }

        
        
for(int i = 0; i < no_right_methods.length; i ++{
            
if (method_name.equals(no_right_methods[i])) {
                result 
= method.invoke(delegate, args);
                
return result;
            }

        }

        
        
for (int i = 0; i < high_right_methods.length; i++{
            
if (method_name.equals(high_right_methods[i])) {
                
if (rights_set.isHighRight()) {
                    result 
= method.invoke(delegate, args);
                }
 else {
                    System.out.println(rights_set.getName() 
+ "对函数"
                            
+ method_name + "权限不够");
                }

                
return result;
            }

        }


        
return result;
    }


}

 
其中关键就是用bind函数实现代理和业务逻辑的绑定,用InvocationHandler的接口函数invoke具体实现权限管理以及对业务逻辑开展的影响。测试程序为:
//  No rights-user
        System.out.println( " For tom... " );
        RightsSet rights_set1 
=   new  RightsSet( " Tom " 3 );
        IMyBiz tom_biz 
=  (IMyBiz)  new  RightHandler().bind( new  MyBiz(),
                rights_set1);
        tom_biz.biz_hight_right();
        tom_biz.biz_low_right();
        tom_biz.biz_no_right();
        
        
//  Low right-user
        System.out.println( " For Jerry... " );
        RightsSet rights_set2 
=   new  RightsSet( " Jerry " 9 );
        IMyBiz jerry_biz 
=  (IMyBiz)  new  RightHandler().bind( new  MyBiz(),
                rights_set2);
        jerry_biz.biz_hight_right1();
        jerry_biz.biz_low_right1();
        jerry_biz.biz_no_right1();
        
        
//  High right-user
        System.out.println( " For Lucy... " );
        RightsSet rights_set3 
=   new  RightsSet( " Lucy " 12 );
        IMyBiz lucy_biz 
=  (IMyBiz)  new  RightHandler().bind( new  MyBiz(),
                rights_set3);
        lucy_biz.biz_hight_right1();
        lucy_biz.biz_low_right();
        lucy_biz.biz_no_right1();
 
其中Tom是no-right用户,Jerry是low-right用户,Lucy是high-right用户,结果如下:
For tom...
Tom 对函数 biz_hight_right 权限不够
Tom 对函数 biz_low_right 权限不够
Any one here
For Jerry...
Jerry 对函数 biz_hight_right1 权限不够
Some one with low rights here 111
Any one here 111
For Lucy...
Some one with hight here 111
Some one with low rights here
Any one here 111
可以看到三个人权限一个高于一个。
总结一下动态代理的优势:比较好的实现了权限管理等非主体业务逻辑和主体业务逻辑的分离,并将这些非主体逻辑集中到InvocationHandler一并处理(针对静态代理的优势),最终提高了可维护性。
有了点 AOP的影子……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值