2015-09-04 34 views
2

我有一些代碼具有大量內部#if DEBUG... #else塊定義的常量的更好的方法;例如:爲條件代碼

public static class C 
{ 
    #if DEBUG 
     public const string FIELDAAA = "VeryLongDescriptiveFieldName"; 
     public const string FIELDBBB = "AnotherLongDescriptiveFieldName"; 
     public const string FIELDCCC = "YetAnotherLongFieldName"; 

     // ... many more field definitions 
    #else 
     public const string FIELDAAA = "F1"; 
     public const string FIELDBBB = "F2"; 

     // Notice that FIELDCCC is missing - whoever added it to the 
     // DEBUG block, forgot to add it here. 
    #endif 
} 

這些字段用於構建第三方服務器的文本請求 - 服務器可以採用任何形式的字段名稱。不過,使用縮寫形式會更有效率,因爲每條消息都有一個大小限制,而當請求變得太大時,必須將其分解爲幾條消息。每條消息都有一定的成本,所以我們的軟件應該在生產中使用短字段名稱,在開發過程中使用長名稱(用於調試)。

有許多與此設置源文件,其中大部分都在DEBUG塊和else區塊不匹配的常量。由於這些不匹配,由於缺少常量,此應用程序的某些部分無法在發佈模式下構建。

我試圖通過刪除巨大的DEBUG塊來解決這個問題,但我需要保持長字段和短字段的名稱定義,同時確保很難錯誤地添加新字段。我也希望將更改數量保持在最低水平 - 這是很多用戶使用的一個大型應用程序,我不想引入重大更改 - 這些字段在許多地方都有使用。

目前,這就是我的想法:

public static class C 
{ 
    public const string FIELDAAA = 
     #if DEBUG 
     "VeryLongDescriptiveFieldName"; 
     #else 
     "F1"; 
     #endif 

    public const string FIELDBBB = 
     #if DEBUG 
     "AnotherLongDescriptiveFieldName"; 
     #else 
     "F2"; 
     #endif 

    public const string FIELDCCC = 
     #if DEBUG 
     "YetAnotherLongFieldName"; 
     #else 
     "F3"; 
     #endif 

    // more constants 
} 

我不知道我是否有心理障礙,但我想不出什麼更好的顯著。有沒有更好的方法可以讓我做我想做的事情,但使用不太麻煩的設置?使用#if DEBUG我沒有問題,但這感覺很髒,如果有更清潔的解決方案,我更喜歡這個。

+0

您可以從資源文件中讀取它們,並具有用於調試的不同文件。 – cubrr

+1

我意識到沒有更好的。你的解決方案結束了缺少的常量問題,因爲如果在這個變化之後有人'忘記'添加兩個常量,那麼他最好改變工作。 – Steve

回答

3

是的,有! (總是)

恕我直言,我認爲你可以使用類似工廠模式(http://www.oodesign.com/factory-pattern.html)或使用DI(Depedency注射 - https://en.wikipedia.org/wiki/Dependency_injection

這樣,你應該刪除公共靜態C級,你可以用另一這樣的解決方案如下:

這樣你就不會只用#if調試你的解決方案,而是使用工廠模式來實例化「正確的」常量,這樣你就不用擔心每個字符串。

你的代碼編譯,因爲接口德曼ds表示每個類都正確執行,而沒有集合的屬性將不允許程序員更改內容。

在正在使用您的常量,你可以做的類。

public class UsingClass 
{ 
    IConstantClass constants; 
    public UsingClass(){ 
     constants f = new FactoryConstants(); 
    } 
} 

public class FactoryConstant 
{ 
    public FactoryConstant() 
    { 
    } 
    public IConstantClass GetConstant() 
    { 
     #if DEBUG 
     return new ConstantsDebugMode(); 
     #else 
     return new ConstantsProduction(); 
     #endif 
    } 
} 

public interface IConstantClass 
{ 
    public string FIELDAAA {get;set;} 
    public string FIELDBBB {get;set;} 
} 

public class ConstantsProduction : IConstantClass 
{ 
    public string FIELDAAA 
    { 
     get { return "ProductionString"; } 
     set { } 
    } 
    public string FIELDBBB 
    { 
     get { return "ProductionString2"; } 
     set { } 
    } 
} 

public class ConstantsDebugMode : IConstantClass 
{ 
    public string FIELDAAA 
    { 
     get { return "ReallyLongStringDebugMode"; } 
     set { } 
    } 
    public string FIELDBBB 
    { 
     get { return "ReallyLongStringDebugMode2222"; } 
     set { } 
    } 
} 

PS .:我沒有測試這個代碼,但它應該工作。

的Depedency注射液,你會在配置文件中配置的系統應該如何實現的接口類(IConstantClass),所以你不需要每次都需要工廠類實例化。

你可以改變我的代碼,並通過一個接口的構造方法的類或與正確的解決方案的屬性。

+0

我想也許他需要變量是'const'。如果不是這樣很好。 – usr

+0

我提高了你的答案,但我仍在考慮是否應該接受它。我在開始的時候考慮了這種方法,並且最初放棄了這種方法,因爲它需要大量的設置才能獲得我認爲值得懷疑的收益。 – xxbbcc

+0

在你的回答之後,我給了它另一個想法 - 很明顯,它需要比'const'方法更多的設置。它提供了更多的靈活性,但這些點也成爲可能的錯誤點。這肯定會提供用兩組字段定義來測試代碼的能力(不可能用常量 - 這是我最初沒有想到的一個方面)。我會認爲這是多一點 - 我想看看是否有另一種方法值得考慮。 – xxbbcc