我建議你從設計開始首先,不管你使用什麼語言。 想象一下,您將需要添加一個具有不同 菜單項集的更多用戶類型(例如「Guest」)。 然後需要做什麼?添加一個「if」語句,基本上覆制粘貼。 這並不好。現在想象一下當你有10個用戶類型時會發生什麼。 您的開關盒聲明將成爲巨型怪物,團隊中的每個人(即使您)都會害怕在其中添加新項目或更改現有項目。
好吧,那是可悲的,我們現在有一些樂趣:)
理想情況下,你的「客戶」的代碼,我想你要放到Page_Load方法將只有一個行:
protected void Page_Load(object sender, EventArgs e){
BuildMenu();
}
就怎麼爽是隻有一個在你的方法行,有一切「奇蹟般地」整理出來。
比方說,我們有某種政策調整我們用戶類型的可用項目。 基本的接口是非常簡單的:
public abstract class MenuItemsPolicy{
public abstract List<MenuItem> GetMenuItems();
protected virtual MenuItem CreateMenuItem(string text, string url){
//add parameter checks, etc.
MenuItem item = new MenuItem();
item.Text = text;
item.NavigateUrl = url;
return item;
}
}
目前,我們有兩個用戶類型,所以我們將會有確切的兩種實現方式。 請求程序:
public class RequestorMenuItems : MenuItemsPolicy{
public override List<MenuItem> GetMenuItems(){
return new List<MenuItem>(){
CreateMenuItem("Request A New Course", "~/Courses/RequestNewCourse.aspx"),
CreateMenuItem("View My New Course Requests", "~/Courses/ViewMyCourseRquests.aspx")
};
}
}
和管理員(注意這裏的「合併」是)
public class AdministratorMenuItems : MenuItemsPolicy{
public override List<MenuItem> GetMenuItems(){
List<MenuItem> resultingMenuItems = (new RequestorMenuItems()).GetMenuItems();
resultingMenuItems.Add(CreateMenuItem("View Un-Approved Requests", "~/Administration/ViewUnAprroved.aspx"));
return resultingMenuItems;
}
}
正如你所看到的,我們獲取申請者的項目,然後再增加一個項目出現。 如果將來需要更改,您的客戶端/調用代碼將不知道 的實現細節,因爲您依賴抽象實體。這意味着你不需要改變你的客戶端/調用代碼,規則就會改變;或者將來需要更改特定用戶類型的可用鏈接。
爲了簡化的例子中,我用枚舉的用戶類型:
public enum UserAccessType{
Requestor = 0,
Administrator = 1
}
現在,讓我們對實現一起來看看。 我把一個簡單的標準asp.net菜單控件拖到頁上:
<form id="form1" runat="server">
<asp:menu runat="server" Id="mainMenu"></asp:menu>
<div>
而這裏的「代碼隱藏」:
public partial class _Default : System.Web.UI.Page{
//We will initialize this variable a bit later
//for example from URL parameter ?userType=1 or something like that
private UserAccessType _currentUserAccess;
//Ideally, dictionary should be a member of a class
//I left a simple dictionary just to avoid over-complicaation
private readonly Dictionary<UserAccessType, MenuItemsPolicy> _userMenuItems = new Dictionary<UserAccessType, MenuItemsPolicy>();
protected override void OnInit(EventArgs e){
//Associating our user types with Menu Items
_userMenuItems.Add(UserAccessType.Administrator, new AdministratorMenuItems());
_userMenuItems.Add(UserAccessType.Requestor, new RequestorMenuItems());
//Init the Current User/Access Type. For example, you can read the value from Request["UserType"]
//Here I've just assigned a value
_currentUserAccess = UserAccessType.Administrator;
base.OnInit(e);
}
protected void Page_Load(object sender, EventArgs e){
BuildMenu();
}
private void BuildMenu(){
mainMenu.Items.Clear();
var menuItems = GetMenuItems();
foreach(var item in menuItems){
mainMenu.Items.Add(item);
}
}
private List<MenuItem> GetMenuItems(){
MenuItemsPolicy currentPolicy = _userMenuItems[_currentUserAccess];
return currentPolicy.GetMenuItems();
}
}
我希望,上面的例子回答您的問題。 這個例子當然並不理想。但是,它有助於保持代碼的相對清潔和可維護性。
P.S.我建議您閱讀文章: http://objectmentor.com/resources/articles/Principles_and_Patterns.pdf
參考OCP示例 - 您會看到,它與您的情況有多接近。
感謝閱讀:)
謝謝米哈伊爾,我列舉了我提到的用戶,我認爲這是一個很好的計劃,所以非常感謝您將它列入您的回覆。我會閱讀這篇文章,並通過我的項目工作。乾杯- – Jazzy 2012-04-17 14:48:11