我已经编写了许可证系统,该系统会检查许可证的不同方面(例如,开始日期,结束日期,系统限制等)。在示例中,我对许可证有限制,该许可证表示您不能创建超过5个用户帐户。我有一个方法(例如bool NumberOfUsersIsCoveredByLicense),它调用一个常用方法(例如bool IsValidLicense)。 IsValidLicense将检查许可证文件是否被操作,过期等。
现在的问题是错误输出。正如您所看到的,我有方法具有bool返回值,因此我知道存在许可证违规,但我不知道许可证检查的哪个部分失败。 所以我正在考虑如何返回一个值,该值描述了违反许可证的哪一部分。最简单的方法是返回一个字符串值,我会做类似
的事情var licenseValidationResult = NumberOfUsersIsCoveredByLicense(4)
if(licenseValidationResult.Equals(String.Empty))
{
//Success
}
else
{
ErrorMessage = GetErrorMessageByErrorCode(licenseValidationResult);
}
因此,如果许可证有效,我将返回一个空字符串,如果它无效,它将以error1; error2; error3等形式返回错误代码。我实际上不确定,如果这是一个好的soulution。另一种可能性是枚举,如下所示:
[Flags]
public enum LicenseErrorCodes
{
None = 0x00,
LicenseExpired = 0x01,
LicenseManipulated = 0x02,
MaxNumberOfUsersReached = 0x04,
[...]
}
但是,我不确定这是否是一个很好的解决方案。是否有任何“常用方式”/最佳实践来解决这样的问题?
答案 0 :(得分:2)
如果许可证违规被视为失败或错误,那么将异常抛到失败的位置可能是合理的。
所以,定义你的InvalidLicenseException
..
答案 1 :(得分:1)
如何使用out parameters。因此,您仍然可以返回成功或失败的布尔值,还可以向isValidLicence方法添加一个out messageString参数。或者定义一个License Violation类并使用它。
答案 2 :(得分:1)
如果要限制失效的可能状态,可以使用枚举。这将允许您的UI等处理每个可能的状态。如果您的验证系统中有许多变体状态,那么我建议您创建一个包含相关信息的验证类,并从您的验证函中返回,例如:
static IValidationInfo Validate(ILicense someLic)
{
// Implementation
}
interface IValidationInfo
{
IEnumerable<LicenseErrorCodes> KnownErrors { get; }
IEnumerable<string> WierdErrors { get; }
}
创建类是一个轻量级的过程,因此与建议的“out”解决方案相比,性能考虑因素将是最小的。
编辑: 此外,我还建议不要使用验证器的例外。至少在我看来,验证器应该被设计为接受输入并验证它。让消费者处理它吐出的任何无效数据错误,而不必在try {} catch {}块中执行此操作。例外情况应仅用于消费者无法直接处理的不可预测/外部问题,例如:文件访问问题或COM失效。