假设我们有一个函数可以在 MVC 应用程序的系统中更改用户的密码:
public JsonResult ChangePassword
(string username, string currentPassword, string newPassword)
{
switch (this.membershipService.ValidateLogin(username, currentPassword))
{
case UserValidationResult.BasUsername:
case UserValidationResult.BadPassword:
// abort: return JsonResult with localized error message
// for invalid username/pass combo.
case UserValidationResult.TrialExpired
// abort: return JsonResult with localized error message
// that user cannot login because their trial period has expired
case UserValidationResult.Success:
break;
}
// NOW change password now that user is validated
}
membershipService.ValidateLogin()
返回一个UserValidationResult
枚举定义为:
enum UserValidationResult
{
BadUsername,
BadPassword,
TrialExpired,
Success
}
作为一个防御性程序员,我会改变上面的内容ChangePassword()
如果存在无法识别的情况则抛出异常的方法UserValidationResult
值回自ValidateLogin()
:
public JsonResult ChangePassword
(string username, string currentPassword, string newPassword)
{
switch (this.membershipService.ValidateLogin(username, currentPassword))
{
case UserValidationResult.BasUsername:
case UserValidationResult.BadPassword:
// abort: return JsonResult with localized error message
// for invalid username/pass combo.
case UserValidationResult.TrialExpired
// abort: return JsonResult with localized error message
// that user cannot login because their trial period has expired
case UserValidationResult.Success:
break;
default:
throw new NotImplementedException
("Unrecognized UserValidationResult value.");
// or NotSupportedException()
break;
}
// Change password now that user is validated
}
我一直认为像上面最后一个片段这样的模式是最佳实践。例如,如果一位开发人员收到这样的要求:现在当用户尝试登录时,如果出于某种业务原因,他们应该首先联系业务部门,该怎么办?所以UserValidationResult
的定义更新为:
enum UserValidationResult
{
BadUsername,
BadPassword,
TrialExpired,
ContactUs,
Success
}
开发者改变了主体ValidateLogin()
方法返回新的枚举值(UserValidationResult.ContactUs
)适用时,但忘记更新ChangePassword()
。如果没有开关中的例外情况,当用户的登录尝试根本不应该被验证时,仍然允许用户更改其密码!
是我一个人这样,还是这个default: throw new Exception()
一个好主意?我几年前看到过它,并且总是(在摸索它之后)认为它是最佳实践。