2015-09-04 51 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