如果您看到這個題目,覺得有點怪,那說明你是一個高人,最起碼比我高的多,呵呵。
前幾天做了一個公用后台管理系統的項目,其中有一個地方涉及到權限管理的,即為每一個按鈕賦一個權限,然后它權限匯總到角色表里,即一種角色有一些操作權限
,表結構如下:
我們看到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是委托類型的基類