我在通用权限的设计(上)以及通用权限的设计(下)两文中简单的介绍了一种权限设计的思路。
为了把做法说清楚,我采用了最简单的设计来说明问题,其他涉及到的实际问题,我都没有详细说明。并且我在通用权限的设计(下)一文中已经说了这种方法必然有其适用的范围,在这里我不妨把这个适用范围说得清楚一点:首先是权值的存放,功能点的权值必须满足2的n-1次方,也就是说如果我们存放权值的类型是int类型的话,那么理论上我们这种做法只能适用32个功能点,也就是2的31次方为最大那个权值。如果我们采用bigint类型来存放,那么我们理论上可以做64个功能点的,也就是2的63次方为最大那个权值。但是如果我们的系统所需要的功能点远远不止64个,那是不是就无法采用这种二进制按位与、按位或的做法了?其实答案是否定的,我们不妨把功能点分组,也就是所谓的按模块划分,假设有如下的情况:
公告模块 增加—— 0001 0001 删除—— 0001 0010 修改—— 0001 0100 查找—— 0001 1000 新闻模块 增加—— 0010 0001 删除—— 0010 0010 修改—— 0010 0100 查找—— 0010 1000 我们假设系统有公告以及新闻两个模块,我们用八位二进制码的前四位来表示所属的模块,用后四位来表示模块下面对应的功能点,模块与功能点又各自满足2的n-1次方的规律,也就是有公告模块的增加操作的功能点是 0001 0001 前四位代表模块,不同模块前四位必须满足2的n-1次方,不能重复,后四位代表对应模块下面的功能点,功能点必须满足2的n-1次方,但是只要求在模块内不重复就行。也就是如果有公告的增加操作为 0010 0001,与新闻模块的增加操作 0001 0001比较可以看出前四位是不同的,并且满足2的n-1次方,后四位却是相同的,但是二者总体来看的话却是代表不同的数,分别为17以及33。
讲到这里你是否已经明白怎么回事了? 如果我们采用这种模块划分的做法的话,我们创建角色以及更改角色的时候,只需要把功能点的权值相加改成功能点的权值按位或操作即可,即如果角色B具有公告模块的增加操作与新闻模块的增加操作的时候就应该进行 0001 0001 | 0010 0001 = 0011 0001;其他判断与操作均与通用权限的设计(下)说的一样。
那么假如我们用64位来存放权值,并且前54位我们用来保存模块,后10位我们来保存模块对应的功能点(实际上大部分模块的功能点都只是增删改查4个就够了),也就是说我们实际上可以支持的功能点总数就是:54*10=540个,一般系统应该够用了,如果你的系统的模块较多,模块对应的功能点又较少,我们可以调整模块与功能点所占位数的比例,以此来适用你的系统