我想把我的错误分开,因为当定义它们时,它们有很多细节,这是一个错误模型:
public interface IErrorResult : IResult
{
string Code { get; set; }
string Message { get; set; }
string Description { get; set; }
}
这方面的一个例子是:
public static class CheckoutError
{
public static ErrorResult Purchased = new ErrorResult
{
Code = CheckoutErrors.AlreadyPurchased,
Message = "License already bought.",
Description = "A license for this account already exists."
};
public static ErrorResult Expired = new ErrorResult
{
Code = CheckoutErrors.Expired,
Message = "Checkout Expired.",
Description = "The checkout session expired, please try again."
};
public static ErrorResult NotFound = new ErrorResult
{
Code = CheckoutErrors.NotFound,
Message = "Checkout not found.",
Description = "This checkout session doesn't exist."
};
}
我之所以单独定义这些,是因为它们可以重复使用,并且在必要时可以更容易地修改它们。
这些错误在验证器中使用,验证器在调用业务逻辑之前被调用,如下所示:
public class CheckoutValidator : ICheckoutValidator
{
private readonly ICheckoutSessionRepository _checkoutSessionRepository;
private readonly ILicenseValidator _licenseValidator;
public CheckoutValidator(ICheckoutSessionRepository checkoutSessionRepository)
{
_checkoutSessionRepository = checkoutSessionRepository;
}
public async Task<IResult> ValidateSession(string userId)
{
var checkout = await _checkoutSessionRepository.GetBySession(userId);
if (checkout == default(CheckoutSession) || checkout.User.AspNetUserId != userId)
{
var error = CheckoutError.NotFound;
error.Status = ResultStatusEnum.NotFound;
return error;
}
if (DateTime.Now > checkout.Expires)
{
var error = CheckoutError.Expired;
error.Status = ResultStatusEnum.Invalid;
return error;
}
return new Result
{
Status = ResultStatusEnum.Valid
};
}
}
我想知道,这种设计是常用的吗?我觉得它可以变得更简单,我已经克服了复杂的事情,但我很难看到在哪里以及哪些地方可以改变和改进
我看到并使用了一些错误模型
简单成功/失败的替代方案
bool Try*(out T result)
-模式- 返回null
- 返回一个可能的Monad
提供有关故障的附加信息的替代方案
- 引发异常
- 返回结果对象
每个选项都有各种缺点/优点。关于异常与结果对象,一种观点是,异常应用于"异常",即意外和罕见错误,而结果对象应用于常见和/或预期错误内存不足可能是前者的例子,而无效用户可能是预期错误的例子。
关于您的具体实现,有几个问题:
- 您的结果对象不是泛型的,那么如果您需要返回一些任意对象,您会怎么做?调用方似乎必须进行一些强制转换才能从返回的对象中获得任何有用的东西,这通常会导致代码混乱。我建议将result对象设为泛型对象,从这个实现中获得灵感
- 您有Errors是静态(即全局(对象,但有公共setter。这是一个很大的拒绝,很容易导致奇怪的行为。例如,考虑是否从多个线程访问错误对象(属性可能随时更改(,或者忘记设置其中一个属性(它将保留最后一个值(。要么使对象不可变,要么将它们更改为返回新对象的方法