【问题标题】:"Helper" Class - how to implement better“帮手”类——如何更好的实现
【发布时间】:2019-06-23 05:43:48
【问题描述】:

例如,我的类的方法应该在使用前验证输入值。建议,方法的2个参数是:

int start
int count

我们应该验证,start 不小于 0(应该是 0 或更大),count 应该在 0..999 范围内。如果这2个参数有效,我们继续执行我们的方法,否则抛出异常BillComInvalidRangeException

public class BillComInvalidRangeException : Exception
{
    const string invalidRangeMessage = "The range is not valid. 'Start' should be greater than 0, 'Count' in range 0..999.";

    public BillComInvalidRangeException(int start, int count) : base($"{invalidRangeMessage} Passed 'Start' : {start}, 'Count' : {count}")
    {
    }
}

我想遵循 SRP 并再创建一个名为 ValidateListRange 的类。我可以通过 3 种方法实现它:

  1. 验证方法中的值:

    public bool Validate(int start, int count)
    {
        return !(start < 0
        || count < 0
        || count > 999);
    }
    

然后只是使用:

var validateObject = new ValidateListRange();
if (!validateObject.Validate(start, count))
    throw new BillComInvalidRangeException(start, count);
  1. 在静态方法中验证值:

    public static bool Validate(int start, int count)
    {
        return !(start < 0
            || count < 0
            || count > 999);
    }
    

然后用于使用:

        if (!ValidateListRange.Validate(start, count))
            throw new BillComInvalidRangeException(start, count);

具有相同功能的更短的记录。那么我们的ValidateListRange 类就是简单的 Util 类,它可以在项目中包含许多类似这样的方法(验证、生成等)。

但是使用非静态类我们有一个巨大的好处——我们可以使用接口然后传递必要的验证对象而不改变我们的项目源代码。例如,将来我们应该验证 9999,而不是 999,我们可以编写 ValidateListRange 类的新实现。如果有必要

哪种方法更好?或者任何其他方法?

【问题讨论】:

  • 在我看来,最好的方法,因为它不使用任何类型的字段,所以没有理由声明一个新的对象实例来调用这个方法
  • 第二种方法(静态)当然更好,因为不需要内存分配和垃圾收集。我也可以考虑定义一个带有嵌入式IsValid 属性的InputData 结构。但这并没有太大的区别。
  • @Max 但它是额外的结构,我不想拉到外部接口
  • @OlegSh,同意这一点。我不知道所有细节,所以这只是另一个建议,不一定是最好的。但是,如果您有大量输入参数,其中一些应该在大多数情况下默认,则这种方法可能看起来更准确。到目前为止,我认为您的静态验证器是最好的方法。

标签: c# helper


【解决方案1】:

Oleg,我不确定您在抛出该特定异常方面有多坚持,但您考虑过吗?:

  1. FluentValidation (https://www.nuget.org/packages/fluentvalidation)

  2. 代码合同 (https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts)

【讨论】:

  • 我了解合约(但还不深入)和 FluentValidation。对于 FluentValidation,我们应该使用额外的类(我不想让这两个参数的外部接口更复杂,这对我的库的客户来说更清楚,startcount)。对于合同 - 我会阅读。但是为什么异常是不好的方法呢?
  • 我认为代码合同不再是最新的了。 github.com/Microsoft/CodeContracts/issues/476
  • 我对异常是一种不好的方法没有意见。我不确定不同的框架如何处理引发自定义异常。我同意 Code Contracts 可能没有得到很好的支持,但是您的输入验证方法比 FluentValidation 更尖叫代码合同。我更喜欢 FluentValidation,并在很多项目中使用它。
  • 澄清一下,我喜欢 FluentValidation,因为它更易于测试。
  • 我同意你的观点,在这个例子中,Fluent Validation 是一个很好的方法。但是当我提出这个问题时,我想得更笼统。 tValidate 里面可以是一些更复杂的逻辑,不仅仅是验证数据:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 2013-03-30
相关资源
最近更新 更多