<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)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    常去的網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 又硬又粗又长又爽免费看| 免费一级黄色毛片| 国产亚洲精品成人a v小说| 亚洲乱理伦片在线观看中字| 四虎在线最新永久免费| 亚洲色av性色在线观无码| 免费的全黄一级录像带| 婷婷亚洲综合五月天小说| 一个人免费日韩不卡视频| 亚洲an天堂an在线观看| 最近中文字幕高清免费中文字幕mv| 亚洲AV无码国产精品麻豆天美| 国产永久免费高清在线| 亚洲av无码一区二区三区乱子伦 | 亚洲欧洲精品成人久久奇米网 | 免费a级黄色毛片| 曰批全过程免费视频观看免费软件| 无码不卡亚洲成?人片| 国产成人无码精品久久久免费| 亚洲国产精品SSS在线观看AV| 99爱免费观看视频在线| 亚洲国产日韩综合久久精品| 国产裸模视频免费区无码| 无码AV动漫精品一区二区免费 | 中文字幕亚洲综合小综合在线 | 国产免费牲交视频免费播放| 亚洲精品无码成人片久久| 精品熟女少妇av免费久久| 亚洲色大成网站www尤物| 亚洲国产精品人人做人人爱| a在线免费观看视频| 亚洲毛片基地日韩毛片基地| 全免费一级毛片在线播放| 九九免费精品视频在这里| 亚洲v高清理论电影| 免费看的黄色大片| 手机看片国产免费永久| 亚洲av乱码一区二区三区香蕉 | 18禁男女爽爽爽午夜网站免费| 最新亚洲春色Av无码专区| 国产亚洲精品自在线观看|