回到目录
如果您看到这个题目,觉得有点怪,那说明你是一个高人,最起码比我高的多,呵呵。
前几天做了一个公用后台管理系统的项目,其中有一个地方涉及到权限管理的,即为每一个按钮赋一个权限,然后它权限汇总到角色表里,即一种角色有一些操作权限
,表结构如下:
我们看到OperatorAuthority就是操作权限的意思,它是个int类型的,一个role有一个OperatorAuthority,那我们应该怎么把多个权限存储到OperatorAuthority字段里呢?
这时,我想到了枚举类型的位运算,所以我把权限枚举设计成了这样:
1 [Flags]
2 public enum UserOperatorRole
3 {
4 #region 通用操作权限
5
6 /// <summary>
7 /// 没有任何操作权限
8 /// </summary>
9 [Description("没有权限")]
10 NoneAny = 1,
11 /// <summary>
12 /// 查看事件
13 /// </summary>
14 [Description("查看事件")]
15 ReadEvent = 2,
16 /// <summary>
17 /// 添加事件
18 /// </summary>
19 [Description("添加事件")]
20 AddEvent = 4,
21 /// <summary>
22 /// 修改事件
23 /// </summary>
24 [Description("修改事件")]
25 ModifyEvent = 8,
26 /// <summary>
27 /// 删除事件
28 /// </summary>
29 [Description("删除事件")]
30 DeleteEvent = 16,
31 /// <summary>
32 /// 审批
33 /// </summary>
34 [Description("审批")]
35 ApproveEvent = 32
36
37 #endregion
38
39
40
41
42
然后在存储时,使用枚举的位运算,对它进行求和即可,如查看事和修改事件的结果被存储为10,即它只能是2和8相加的结果,如果希望了解更多位运算,可以查看我的这篇文章
这样的设计,对于单个项目是没有任何问题的,如果希望添加一种新的功能,如“订阅”,我们只要修改这个枚举类,再为它添加一种订阅的逻辑即可。(当然,这不符合开闭原则了)
但我设计的偏偏是一个“通用的系统”,即可能会有多个不同的项目去引用这个系统,这个系统相当于一个底层的核心系统,这时问题就来了,系统A的权限需要添加一个“撤单”权限,而系统B需要有一个“发布产品”及“管理产品”的权限,这下子我也完蛋了,这种需求被不断的添加进来,我可怎么办呀!
主角登场了,整形也来个们运算吧,首先我把所有公用权限进行统计,放在一张表里,如果其它系统有新需求,在它的权限表里继续添加即可,表结构如下:
这样的设计,我认为完成了,但对于一个int32类型来说,它是否也可以支持按位计算呢?我又一想,枚举类型本来就是继承int,short,long,byte等整形类型的,所以,我认识int32也完全可以支持位运算,结果我的测试表明我的想法是正确的,呵呵。
这时,我们通用按钮的建立,就变成了这样,接收一个Enum这个枚举类型的统一基类,这样不管A系统和B系统自定义什么样的枚举,我都通通接受,呵呵。
1 /// <summary>
2 /// 按钮对象,只产生按钮,对按钮的click等事件需要在具体页面自己添加
3 /// </summary>
4 /// <param name="html"></param>
5 /// <param name="buttonName">按钮ID</param>
6 /// <param name="displayName">按钮显示名称</param>
7 /// <param name="userOperatorRole">按钮权限</param>
8 /// <param name="buttonType">按钮类型</param>
9 /// <returns></returns>
10 public static MvcHtmlString CreateButton(this HtmlHelper html, string buttonName, string displayName, Enum userOperatorRole, ButtonType buttonType)
11 {
12 var tag = new TagBuilder("input");
13 tag.AddCssClass("button");
14 tag.Attributes["Name"] = buttonName;
15 tag.Attributes["ID"] = buttonName;
16 tag.Attributes["Value"] = displayName;
17 tag.Attributes["Type"] = buttonType.ToString();
18 if ((Convert.ToInt32(SessionAction.ReadSession("UserOperatorRole")) & Convert.ToInt32(userOperatorRole)) == 0)
19 {
20 tag.Attributes["disabled"] = "disabled";
21 tag.AddCssClass("button gray");
22 }
23 return MvcHtmlString.Create(tag.ToString());
24
程序员在开发时,枚举类型起到了直观,准确和可读性强的优点,所以,对于一些固定的少限的元素集可以采用枚举类型和存储。
小知识:Enum是枚举类型的基类
Delegate是委托类型的基类
回到目录
作者:仓储大叔,张占岭,
荣誉:微软MVP
!