条件代码的更好方法
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 或使用正确的解决方案传递给 属性。
我有一些代码在 #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 或使用正确的解决方案传递给 属性。