【发布时间】: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 种方法实现它:
-
验证方法中的值:
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);
-
在静态方法中验证值:
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,同意这一点。我不知道所有细节,所以这只是另一个建议,不一定是最好的。但是,如果您有大量输入参数,其中一些应该在大多数情况下默认,则这种方法可能看起来更准确。到目前为止,我认为您的静态验证器是最好的方法。