我是 OOP 的新手,所以我需要帮助来了解这是否是处理它的正确方法。我有一个 3 层 Web 项目(+ DTO),我试图了解这是从业务对象返回“错误”到表示层的最佳方式。特别是现在我正面临这个创建用户的问题。假设我想在网站注册时在数据库中创建用户,我需要告诉实际用户用户名或电子邮件是否已经被使用(这只是一个例子)。
例如,ASP.NET Membership.CreateUser() 方法通过引用传递一个 MembershipCreateStatus 对象,因此该方法用于返回一个 Enum(位于另一个命名空间中......)以传递尝试的状态,这可能是 DuplicateEmail,重复用户名,等等。
我根据异常实现了另一种方式,但我想听听你的意见。在创建用户的 BLL 管理器类中,我以这种方式创建了一个嵌套的 Excpetion 类和嵌套的 Enums 错误类型:
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