我是OOP的新手所以我需要帮助才能理解这是否是处理它的正确方法。 我有一个3层Web项目(+ DTO),我试图理解这是将Business Objects返回到表示层的“错误”的最佳方法。 特别是现在我正面临这个创建用户。假设我想在网站注册时在数据库中创建用户,我需要告诉实际用户是否已经使用了用户名或电子邮件(这只是一个例子)。
例如,ASP.NET Membership.CreateUser()方法传递一个MembershipCreateStatus对象byRef,因此该方法用于返回一个枚举(位于另一个命名空间...)以传递尝试的状态,这可能是DuplicateEmail,DuplicateUserName等。
我基于异常实现了另一种方式,但我希望你对此有所了解。在创建用户的BLL管理器类中,我以这种方式创建了一个嵌套的Excpetion类和嵌套的错误类型的枚举:
Public Class UserManager
Public Enum ErrorType
DatabaseError = 1
UserExists = 2
EmailExists = 3
End Enum
Public Class ManagerException
Inherits Exception
Public Property ErrorType As ErrorType
Public Property SuggestedUserName As String
Public Property SuggestedEmail As String
Public Sub New()
MyBase.New()
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, inner As Exception)
MyBase.New(message, inner)
End Sub
End Class
Public Function CreateUserLogin(user As EvaVwUserLogin) As Guid
If user Is Nothing Then
Throw New ApplicationException("No user suppied")
End If
If String.IsNullOrWhiteSpace(user.Password) OrElse String.IsNullOrWhiteSpace(user.UserName) Then
Throw New ApplicationException("Password or username missing")
End If
If CheckDuplicateUserName() Then
Dim ex As New ManagerException("Username exists")
ex.ErrorType = ErrorType.UserExists
ex.SuggestedUserName = "this username is free"
Throw ex
End If
End Function
End Class
然后在UI层(后面的aspx代码)中,我调用管理器并检查异常,如下所示:
Dim userManager As New UserManager
Try
userManager.CreateUserLogin("test", "test")
Catch ex As UserManager.ManagerException
If ex.ErrorType = userManager.ErrorType.UserExists Then
Dim suggestedUsername = ex.SuggestedUserName
' Display error message and suggested user name
End If
End Try
这是一个正确的方法,考虑到异常和枚举都非常特定于这个管理器,所以如果我沿着这条路线走下去,每个管理器都会有它的嵌套ManagerException和相关的枚举吗?
提前感谢您的意见。
跟进Brian和Cyborg友好建议的“自定义代码”场景(我标记他的答案只是因为它更完整Brian也许其他用户对MS建议感兴趣)你认为嵌套自定义返回对象和相关枚举吗?经理班是个好主意? 由于这些枚举将与此经理类严格相关(并且BLL中的每个managar类都有自己的),您认为我仍然可以使用它们作为状态代码传递吗?
编辑:我这样重构了......你认为没关系吗?Public Class UserManager
Public Enum ErrorType
DatabaseError = 1
UserExists = 2
EmailExists = 3
End Enum
Public Class ErrorData
Public Property ErrorType As ErrorType
Public Property SuggestedUserName As String
Public Property SuggestedEmail As String
End Class
Public Function CreateUserLogin(username As String, password As String, ByRef errorData As ErrorData) As Guid
Dim user As New EvaVwUserLogin
user.UserName = username
user.Password = password
Return CreateUserLogin(user, errorData)
End Function
Public Function CreateUserLogin(user As EvaVwUserLogin, ByRef errorData As ErrorData) As Guid
If user Is Nothing Then
Throw New ApplicationException("No user object")
End If
If String.IsNullOrWhiteSpace(user.Password) OrElse String.IsNullOrWhiteSpace(user.UserName) Then
Throw New ApplicationException("Missing password or username")
End If
Dim hashedPassword As String
hashedPassword = Crypto.HashPassword(user.Password)
If UserExists(user) Then
errorData.ErrorType = ErrorType.UserExists
errorData.SuggestedUserName = "this username is free"
Return Nothing
End If
.....
End Function
End Class
在表达层:
Dim userManager As New UserManager
Dim managerError As New UserManager.ErrorData
Dim userId As Guid
userId = userManager.CreateUserLogin("test", "test", managerError)
If userId = Nothing Then
If managerError.ErrorType = userManager.ErrorType.UserExists Then
Dim suggestedUserName = managerError.SuggestedUserName
' Do something with suggested user name
End If
End If
答案 0 :(得分:2)
为此,我会遵循Membership API的功能。从业务组件返回枚举,视图可用于检查响应。因此,您返回一个枚举,其中包含您向ASP.NET页面提及的值,并检查其中的类型。你可以做你正在做的事情,但从我看到的我不认为这是必要的;另外,抛出异常是很昂贵的。
澄清我的意思是enum是从业务组件的调用者返回它,而不是通过异常。
答案 1 :(得分:2)
(这个答案只是为@BrianMains建议使用返回代码而不是异常提供支持。相关文档太大而无法用于评论。)
关于例外的MSDN文档:
抛出或处理异常时会使用大量系统资源和执行时间。抛出异常只是为了处理真正特殊的条件,而不是处理可预测的事件或流量控制。例如,如果方法参数无效,您的应用程序可以合理地抛出异常,因为您希望使用有效参数调用方法。无效的方法参数意味着发生了特殊的事情。相反,如果用户输入无效,不会抛出异常,因为您可能希望用户偶尔输入无效数据。在这种情况下,请提供重试机制,以便用户输入有效的输入。
仅针对特殊情况抛出异常,然后捕获适用于大多数应用程序的通用异常处理程序中的异常,而不是适用于特定异常的处理程序。这种方法的基本原理是大多数错误都可以通过验证和错误处理代码来处理错误;没有异常需要抛出或抓住。通用异常处理程序捕获应用程序中任何位置引发的真正意外异常。
此外,在返回代码足够时不抛出异常;不要将返回代码转换为异常;并且不要经常捕获异常,忽略它,然后继续处理。
http://msdn.microsoft.com/en-us/library/system.exception.aspx
(突出我的)