条件代码的更好方法

Better approach for conditional code

我有一些代码在 #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
}

这些字段用于构建对第 3 方服务器的文本请求 - 服务器可以采用任何一种形式的字段名称。但是,使用短格式要高效得多,因为每条消息都有大小限制,当请求变得太大时,它必须被分解成几条消息。每条消息都有成本,因此我们的软件应该在生产中使用短字段名称,在开发期间使用长名称(用于调试)。

有许多源文件具有此设置,其中大部分在 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 时没有问题,但这感觉很脏,如果有更简洁的解决方案,我会更喜欢。

是的,有!! (总是)

恕我直言,我认为您可以使用工厂模式之类的东西 (http://www.oodesign.com/factory-pattern.html) or use a DI (Depedency Injection - https://en.wikipedia.org/wiki/Dependency_injection.

这样你应该删除 public static C class 并且你可以使用下面这样的另一个解决方案。

这样你就不会将你的解决方案与仅 #if debug 每个字符串联系起来,你可以使用工厂模式来实例化 "right" 常量,这样你就不必担心每个字符串。

您的代码可以编译,因为接口要求每个 class 正确实现,而没有集合的 属性 将不允许程序员更改内容。

在使用常量的 class 中你可以做到。

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.: 我没有测试这段代码,但它应该可以工作。

您将在配置文件中配置系统应如何实现接口 class (IConstantClass) 的 Depedency 注入解决方案,因此您不需要每次实例化工厂 Class.

您可以更改我的代码并在构造函数中将接口传递给 class 或使用正确的解决方案传递给 属性。