2011-09-26 114 views
1

我有一個對象具有兩個屬性:TextType避免在switch語句中硬編碼

爲了避免對類型進行硬編碼,我將它們放在數據庫中,以便將來可以添加它們。目前這些類型是URL, Username and ID

但是,我現在想要運行一個實用程序方法來清理對象的Text字段,該字段基於哪個對象是Type(例如,如果其URL爲「http://」則添加該對象)。

有沒有方法可以在Utilities類中執行此操作,而無需在switch語句/ if else塊中對這些類型進行硬編碼。

switch (type) 
{ 
    case 1: 
     TidyUrl(); 
    case 2: 
     TidyUsername(); 
    case 3: 
     TidyID(); 
    default: 
     break; 
} 

在這個例子中,我從數據庫(「類型」表),這絕不是一件好事硬編碼的ID!

有沒有更好的方法來做到這一點?

+0

無論我使用接口和工廠,數據庫中的枚舉器或方法名稱似乎都無法繞過if/else邏輯,這將需要在哪個地方說哪個是哪個,而這就是我不能鰭d一種避免硬編碼的方法。 – finoutlook

回答

2

傳統上,這是通過使用通用接口來處理的,並動態地構造一個具體的實現來完成實際的工作。

例如:

public interface ITidy 
{ 
    string Tidy(string input); 
} 

則實現

public class UrlTidy : ITidy 
{ 
    public string Tidy(string input) 
    { 
     // do whatever you need to the url 
    } 
} 

等等的其他類型的整理的。現在你需要一種從你正在查看的類型實例化正確的具體類(UrlTidyIdTidy等)的方法。一種方法可能是將類名放在數據庫中,並使用反射來實例化ITidy的正確實現。另一個笏將有一個Factory類,它使用其他方法基於類型實例化正確的ITidy

+0

把類或方法的名字放在數據庫中就像是用另一種方式硬編碼。這可能是更好的,但。 – finoutlook

+0

@finoutlook - 不像硬編碼。它完全相反,允許您動態擴展類型(假設您發佈包含該類的新程序集)。這類似於插件系統,允許您在不釋放軟件的安全性的情況下擴展應用程序的功能。 – Jamiec

+0

是的,我看到它在數據庫中的優勢。使維護更容易,而且您是對的,可以動態更改。 – finoutlook

4

您可以使用枚舉來提高可讀性。

enum MyTypes 
{ 
URL = 1, 
UserName = 2, 
Id = 3, 
} 

switch (myType) 
{ 
    case MyTypes.URL: 
     TidyUrl(); 
    case MyTypes.UserName: 
     TidyUsername(); 
    case MyTypes.Id: 
     TidyID(); 
    default: 
     break; 
} 

此枚舉將需要與數據庫保持協調。

+0

是的,我過去已經這樣做了,但它似乎只是把同一個問題(保持id同步)放在不同的地方。 – finoutlook

+0

@finoutlook - 但至少它是_clear_那個地方。根據我的經驗,您可以在代碼庫中擁有映射_somewhere_。 – Oded

+0

是的,我同意它的更清晰(並且可以將其他映射組合在一起,例如在枚舉器類中),而不是通過代碼傳播。 – finoutlook

3

一種方法是使用多態性。你會爲每個「類型」分別設置不同的類,他們會使用像Tidy這樣的方法來實現一個通用的接口(或者有一個通用的基類),其中每個接口都有自己的邏輯。

+2

還有一個工廠方法,它將查找DB中編碼的類型並創建該類型的新對象。可能使用'switch'語句;) – Oded

+0

@Oded - 的確,無論使用什麼選項,我都必須將我的代碼直接鏈接到數據庫中的內容 – finoutlook

+1

是的,這是真的;但是這種技術避免了這些switch語句的泛濫。你只需要_one_。或者_none_,如果你更喜歡使用反射... –

0

你可以使用enum Type但是它們的常量值必須在編譯時確定。您可以在enum中加入類不變檢查以確保與數據庫一致。

但是如何讓他們在數據庫中使其可擴展?

+0

我認爲你的問題很好,它爲什麼可擴展。數量有限,但數據庫中的某些類型可能共享相同的方法,例如一個新的'UrlWithQuerystring'類型可能使用相同的'TidyUrl()'方法。 – finoutlook

+0

如果您非常熱衷於不對數字進行硬編碼,那麼我上面概述的解決方案應該可以很好地工作。如果您可以爲每種類型創建單獨的類,則可以使用Bonus點,將typeid和handler類放入數據庫表中,並在啓動時初始化處理程序對象並將它們存儲在註冊表中。 –

0

由於奧德說,使用枚舉:

public enum Types 
{ 
    Type1 = 1, 
    Type2 = 2, 
    Type3 = 3 
} 

然後,您可以將您的類型變量轉換爲枚舉,具有整數映射到數據庫ID:

switch ((Types)type) 
{ 
    case Types.Type1: 
     break; 
    case Types.Type2: 
     break; 
    ... 
} 

希望幫助