<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 193,  comments - 520,  trackbacks - 0
    一開始我把控制數據權限寫在業務里,以訂單管理為例,先討論一個最簡單的情況。管理員可以看所有的訂單,而用戶只能看自己的訂單。這里的管理員是一個角色。我會這么寫(一些次要代碼都省略了):

    ???List?getOrders(String?userId){
    ?????????????String?sql;
    ?????????????Role?role
    =orgService.getRoleForUser(userId);
    ?????????????
    if(("admin").equals(role.getName()))
    ???????????????????sql
    ="select?*?from?order";
    ?????????????
    else
    ???????????????????sql
    ="select?*?from?order?where?author="+userId;
    ?????????????Object?o
    =excuteSql(sql);
    ?????????????
    return?excute(o);
    ????????}

    恩,不錯,很好的完成了權限控制。過了沒多久,公司發展了,老板增加了人手,老板發話了,我要設置區域管理員分管不同區域的訂單。管理員分為北京地區管理員,上海地區管理員,其他地區管理員和總管理員。怎么辦?修改代碼吧
    ????List?getOrders(String?userId){
    ?????????????String?sql;
    ?????????????Role?role
    =orgService.getRoleForUser(userId);
    ?????????????
    if(("admin").equals(role.getName()))
    ??????????????????sql
    ="select?*?from?order";
    ?????????????
    else?if("bjadmin").equals(role.getName()))
    ?????????????????????????sql
    ="select?*?from?order?where?area='beijing'";
    ?????????????
    else?if("shadmin").equals(role.getName()))
    ?????????????????????????sql
    ="select?*?from?order?where?area='shanghai'";
    ?????????????
    else?if("qtadmin").equals(role.getName()))
    ?????????????????????????sql
    ="select?*?from?order?where?area='qita'";
    ?????????????
    else
    ???????????????????sql
    ="select?*?from?order?where?author="+userId;
    ?????????????Object?o
    =excuteSql(sql);
    ?????????????
    return?excute(o);
    ????????}

    恩恩,這就搞定了,可怎么也感覺不爽,也許該做點什么。一堆if/else權限判斷讓人心煩,再寫個類把這些sql管理起來好了,那就動手吧
    ??public?class?SqlManager{
    ??????????String?getSql(String?userId){
    ??????????????????String?sql;
    ??????????Role?role
    =orgService.getRoleForUser(userId);
    ??????????
    if(("admin").equals(role.getName()))
    ??????????????sql
    ="select?*?from?order";
    ??????????
    else?if("bjadmin").equals(role.getName()))
    ???????????????????sql
    ="select?*?from?order?where?area='beijing'";
    ??????????
    else?if("shadmin").equals(role.getName()))
    ???????????????????sql
    ="select?*?from?order?where?area='shanghai'";
    ??????????
    else?if("qtadmin").equals(role.getName()))
    ???????????????????sql
    ="select?*?from?order?where?area='qita'";
    ??????????
    else
    ????????????sql
    ="select?*?from?order?where?author="+userId;
    ??????????
    return?sql;
    ??????????}
    ??}

    這樣把權限判斷移到SqlManager里,業務代碼就清爽了很多,再增加管理員就修改SqlManager好了
    ????List?getOrders(String?userId){
    ?????????????String?sql
    =sqlManager.getSql(userId);
    ?????????????Object?o
    =excuteSql(sql);
    ?????????????
    return?excute(o);
    ????????}

    呵呵,看起來還不錯。但是等等,我們的業務方法為什么需要userId這個參數呢,是啊是啊,權限判斷用到了它,但是那和我業務又有什么關系呢,不爽。現在AOP不是很流行嗎,你不用AOP怎么能說明你技術高呢?快用吧快用吧,用不著也要想著方法用。
    業務方法簡化為
    ????List?getOrders(){
    ?????????????String?sql
    ="";
    ?????????????Object?o
    =excuteSql(sql);
    ?????????????
    return?excute(o);
    ????????}

    對excuteSql方法我們來AOP一下,注入權限判斷過的sql.嘿嘿,技術水平又一次得到了顯現。業務方法是簡單了,可我的SqlManager倒是復雜了,還是很不幸福。咋辦?用個配置文件吧,hibernate不是老鼓勵我們把sql寫在配置文件里嗎?
    ????<xml>
    ????????<sql?role
    ="admin">select?*?from?order</sql>
    ????????<sql?role
    ="bjadmin">select?*?from?order?where?area='beijing'</sql>
    ????????<sql?role
    ="shadmin">select?*?from?order?where?area='shanghai'</sql>
    ????????<sql?role
    ="qtadmin">select?*?from?order?where?area='qita'</sql>
    ????????<sql?role
    ="none">select?*?from?order?where?author=?</sql>
    ????</xml>

    這樣SqlManager就可以把行數縮小了,就可以敏捷一點了。
    ????public?class?SqlManager{
    ??????????String?getSql(String?userId){
    ??????????????????String?sql;
    ??????????Role?role
    =orgService.getRoleForUser(userId);
    ??????????sql
    =getSqlfromXml(role.getName());
    ??????????
    return?sql;
    ??????????}
    ??????????
    ??????????String?getSqlfromXml(String?rolename){
    ??????????????????.
    ??????????}
    ??}

    以后再增加權限連類都不用修改了,改xml好了。等等,你是不是把問題太簡單化了。現在不僅僅是訂單,貨物也要這么分區域管理。
    不錯,我們應該想著通用一下了。這樣,把SqlManager抽象一下
    ????????String?abstract?getSqlfromXml(String?rolename);

    然后做幾個子類好了 OrderSqlManager, GoodsSqlManager .
    可是,哥們,書上說,要面向接口編程,你這樣不太好吧。沒事,再接口一下:
    ???public?interface?SqlManagerInterface{
    ???????????String?getSql(String?userId);
    ???}

    還是沒法用啊。也許現在可以看看acegi的provider機制了,把這一大堆SqlManager全部作為provider,根據不同的模塊選擇不同的provider,統一攔截excuteSql方法,生成不同的sql到數據庫執行。xml不爽?db也可以。然后,再然后呢?改你的類名,重構,和acegi整合一下。
    呵呵,完全是個人的一些想法,希望多批評提提意見。我想表達的意思是:也許把數據權限再抽象一些,以組件的形式來減少侵入是可以做到的。

    http://www.tkk7.com/ronghao 榮浩原創,轉載請注明出處:)
    posted on 2007-03-23 18:35 ronghao 閱讀(6718) 評論(6)  編輯  收藏 所屬分類: 權限相關

    FeedBack:
    # re: 對數據權限控制的實驗
    2007-03-24 23:21 | 龍卷風驛站
    比較適合講知識,文筆不錯,贊一個  回復  更多評論
      
    # re: 對數據權限控制的實驗[未登錄]
    2007-03-26 10:15 | 阿蜜果
    你的權限篇寫得不錯,up!  回復  更多評論
      
    # re: 對數據權限控制的實驗
    2007-03-29 10:52 | jerome
    講的不錯,淺顯易懂,深有收獲啊  回復  更多評論
      
    # re: 對數據權限控制的實驗[未登錄]
    2007-10-11 15:29 | MagicYang
    我看到第3段代碼就聯想到:
    1、先把if/else if換成switch語句;
    2、再用多態替換switch語句;
    用戶接口:
    public interface User{
    public abstract List getOrders();
    }

    普通用戶:
    public abstract class User implements User{
    public List getOrders(String userId){
    sql="select * from order where author="+userId;
    Object o=excuteSql(sql);
    return execute(o);
    }
    }

    管理員:
    public abstract class Administrator implements User{
    public List getOrders(String adminId){
    sql="select * from order where area=" + getAreaByAdmin();
    Object o=excuteSql(sql);
    return execute(o);
    }

    protected abstract String getAreaByAdmin();
    }

    北京地區管理員:
    public class BjAdministractor extends Administractor{
    protected String getAreaByAdmin(){
    return "beijing";
    }
    }

    除了訂單,如果貨物也要加入區域管理的話- -!,只需要在普通用戶和管理員兩個抽象類中加入相關的抽象方法,具體的區域管理員里各自實現他們就行了。我的方法是不是很土。。。  回復  更多評論
      
    # re: 對數據權限控制的實驗[未登錄]
    2007-10-11 15:34 | MagicYang
    e...好象User類和User接口重名了  回復  更多評論
      
    # re: 對數據權限控制的實驗[未登錄]
    2007-10-11 15:39 | MagicYang
    以上只是基于你的數據權限控制實驗的所做重構,一般來說不傾向這么做,只把sql的area查詢條件作參數傳遞就行了,你不用這么多xml,我也不用這么多子類。。。不過我覺得這只是你的一個實驗例子而已對吧  回復  更多評論
      
    <2007年3月>
    25262728123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    關注工作流和企業業務流程改進。現就職于ThoughtWorks。新浪微博:http://weibo.com/ronghao100

    常用鏈接

    留言簿(38)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 深夜福利在线免费观看| 久久精品视频免费看| 亚洲国产婷婷六月丁香| 久久久久免费看成人影片| 亚洲av永久无码嘿嘿嘿| 国产hs免费高清在线观看| 日韩免费在线视频| 亚洲av片在线观看| 亚洲国产精品lv| 国产精品无码素人福利免费| 久久www免费人成精品香蕉| 亚洲AV无码成人专区| 不卡一卡二卡三亚洲| 美女视频黄免费亚洲| 美女无遮挡拍拍拍免费视频| 中文字幕亚洲男人的天堂网络| 亚洲一级特黄大片无码毛片| 国产成人免费网站| 永久免费A∨片在线观看| 亚洲AV日韩AV永久无码色欲| 久久亚洲日韩精品一区二区三区| 男人的天堂亚洲一区二区三区 | 亚洲精品日韩专区silk| 日本免费一二区在线电影| 人妻无码久久一区二区三区免费| 国产精品亚洲av色欲三区| 亚洲性色高清完整版在线观看| 国产亚洲av人片在线观看| 永久免费bbbbbb视频| 97久久免费视频| 中文字幕a∨在线乱码免费看 | 黄色片免费在线观看| 国产精品亚洲综合一区在线观看| 日韩精品亚洲人成在线观看| 亚洲电影日韩精品 | 全黄A免费一级毛片| 亚洲人成综合网站7777香蕉| 99ri精品国产亚洲| 亚洲av无码不卡| 亚洲线精品一区二区三区| 免费一级毛片女人图片|