简洁经常使用权限系统的设计与实现(一):构造权限菜单树的N(N>=4)种方法

 权限系统。Web开发常见标准子系统之中的一个。结合自己的一些思考和实践,从本篇開始权限系统的设计与实现之路。



 近期,重构了项目的权限菜单构造过程,向前端返回json格式的权限树。

 这一篇。仅仅是大致介绍下这个问题,并给出4种方法的总体思路。兴许再分别具体介绍这4种方法,再往后介绍完整的权限系统的设计与实现。

 权限表的结构
 acl、parent_acl, 最重要的就是这2个字段。有了这2个字段,就能够构造一棵树了。

 前端须要的json格式:

"data":[{

        "acl":1,

        "children":[{

            "acl":11,

            "children":[{

                "acl":111,

            }]

        } 

方法1
   在数据库再添加1个level字段,最顶层的level就是1。每添加一级level添加1。

   先从数据库依照level升序。获得全部的权限节点。


            List<Map<String, Object>> rootList = new ArrayList<Map<String, Object>>(); 
             Map<String, Map<String, Object>> rootMap = new HashMap<String, Map<String, Object>>(); 
  
for (遍历) {
    

创建节点,添加到根节点map中

if (顶级节点) {

添加到rootList中

} else {

获得父结点,把自己放到父结点的children中

}

}

     遍历结束,rootList即为所求。

   这样的方法是一个同事的思路,关键就是2点,一是维护level(添加和改动的时候都须要)。2是要依照level升序排序。



方法2:数据库不须要level字段。用递归来实现。


    List<Map<String, Object>> finalRootList = new ArrayList<Map<String, Object>>();

List<Map<String, Object>> rootList = findRootList(privilegeList);

List<Map<String, Object>> notRootList = findNotRootList(privilegeList);
               //先找出根节点。再为这些根节点构造子结点 

for (Map<String, Object> root : rootList) {

// 构造子结点

buildChildList(root, notRootList);

finalRootList.add(root);

}

    关键代码buildChildList是个递归函数。


   buildChildList(){
      从全部的非根节点中,找到当前节点的第1级子结点,添加到该节点的children中。


     buildChildList();
  } 

  优点是。不用维护level字段。添加和改动权限的时候,既不用维护level。也不用维护parent_acl。 


方法3:全然依照方法1的思路,唯一不同的是,数据库不维护level字段,而是在查询数据出来之后。手动计算每个节点的level字段,进行排序。

后面的步骤,和方法1基本一样。



    因此。这样的方法的唯一难点就是,怎样计算一颗N叉树每个节点的深度。

方法4: 计算一颗N叉树每个节点的深度,经过实践。至少有2种方法。

a.依照方法2的递归思路,再维护一个level,向child深入一层,level++,返回level--。及时保存当前节点的level,递归结束。level就都计算完毕。

b. 參照网上的一种思路。把“无序的Tree格式的List。转化打印出标准格式Treelist”。


  作者也是依照递归思路实现的,在这个代码的基础上。再维护1个level。就能够了。

a和b的思路类似的地方是。都在递归过程中维护1个level,不同的地方是。a的方法仅仅单纯地计算level,而b不但计算了level,还把节点排序了。

当然,a方法也是能够的。

 


方法5:这样的方法不可行,问题是。存在着反复计算的可能。
 全部节点初始level额外i1.
 找到全部的根节点。

  遍历每个节点,假设发现自己有父结点,就把自己的level和全部父节点的level+1。


  
问题:无法保证多个子结点,都有子结点的时候,他们的父结点,反复添加了level,而反复计算的次数非常难去统计。 


小雷FansUnion-博学的互联网技术工作者,提供付费的IT咨询服务
2014年11月17日

湖北-武汉-循礼门 

原文首发:http://fansunion.cn/article/detail/566.html

原文地址:https://www.cnblogs.com/llguanli/p/6769538.html