w00*_*977 7 vb.net design-patterns
请参阅以下代码:
Imports Microsoft.VisualBasic
Public Class PersonBLL
Private Name As String
Private Age As Integer
Dim objPersonDAL As New PersonDAL
Dim objPerson As Person
Public Sub getPersonByID()
objPerson = objPersonDAL.getPersonByID()
MsgBox(objPerson.Name)
End Sub
End Class
Public Class PersonDAL
Private Name As String
Private Age As Integer
Public Function getPersonByID() As Person
'Connect to database and get Person. Return a person object
Dim p1 As New Person
p1.Name = "Ian"
p1.Age = 30
Return p1
End Function
End Class
Public Class Person
Private _Name As String
Private _Age As Integer
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Public Property Age() As Integer
Get
Return _Age
End Get
Set(ByVal value As Integer)
_Age = value
End Set
End Property
End Class
Run Code Online (Sandbox Code Playgroud)
PersonBLL调用PersonDAL并返回Person对象.这是正确的方法吗?即我已经确定了一个持久化类,并创建了一个相应的DAL类,其中包含一个用于访问数据和返回Person对象的函数.
有评论指出这个问题是"主观的".我同意这一点.我意识到设计取决于项目的要求.是否有任何关于设计类似于SOLID(单一责任等)的DAL的原则.
是的,您的问题演示了将逻辑分层的非常简洁的方法.的PersonBLL类将是业务层的一部分,PersonDAL类将是数据访问层的一部分,并且所述Person类将是数据传输对象(DTO)层的一部分.这是分离图层的一种非常常见的方法,在许多情况下效果很好.
我唯一的建议是:
PersonBLL.getPersonByID从Windows服务或Web服务进行呼叫,则显示消息框将完全不合适.依赖注入
以下是使用DI技术执行此操作的示例:
Public Class BusinessFactory
Public Function NewPersonBusiness() As IPersonBusiness
Return New PersonBusiness(New PersonDataAccess())
End Function
End Class
Public Class PersonBusiness
Implements IPersonBusiness
Public Sub New(personDataAccess As IPersonDataAccess)
_personDataAccess = personDataAccess
End Sub
Private _personDataAccess As IPersonDataAccess
Public Function GetPersonByID() As PersonDto Implements IPersonBusiness.GetPersonByID
Return _personDataAccess.GetPersonByID()
End Sub
End Class
Public Interface IPersonBusiness
Function GetPersonByID() As PersonDto
End Interface
Public Interface IPersonDataAccess
Function GetPersonById() As PersonDto
End Interface
Public Class PersonDto
Private _name As String
Private _age As Integer
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Age() As Integer
Get
Return _age
End Get
Set(ByVal value As Integer)
_age = value
End Set
End Property
End Class
Run Code Online (Sandbox Code Playgroud)
这样做有很多好处.您可以拥有多个可互换的数据访问层实现,因此它更加灵活.此外,如果要对业务类进行单元测试,则可以注入虚假数据访问对象.DI设计避免了许多导致错误的意大利面条代码的陷阱.
对于DI,通常建议您将依赖项对象作为接口而不是具体类型(例如IPersonDataAccess而不是PersonDataAccess).这样做可能有点麻烦,但你很快就会习惯它.由于您经常为每个类创建一个接口,因此将接口放在与该类相同的代码文件中会很方便.因此,例如,PersonBusiness.vb将包含PersonDataAccess类和IPersonDataAccess接口.
为依赖项使用接口而不是类,有两个原因很重要:
它确保了设计的灵活性.您希望能够覆盖依赖关系类型的每个公共成员,以便您可以创建任何类型的具体实现.还有其他方法可以做到这一点.例如,您可以IPersonDataAcess通过简单地PersonDataAccess使用Overrideable修饰符标记类中的每个公共属性和方法来跳过创建接口,但是没有任何强迫您这样做.即使你总是记得这样做,这并不意味着其他人在你的代码上工作会知道他们应该这样做.
DI经常与单元测试捆绑在一起,因为它是确保代码可测试的最佳工具.在单元测试时,特别重要的是你能够覆盖依赖类型中的任何成员,这样你就可以创建一个"假的"对象,它可以按照你需要它的方式工作,以便正确地执行单元测试.这些"虚假"物体被称为模拟物.
你在技术上更诚实地了解你的依赖是什么.实际上,您并不是说您的依赖实际上是PersonDataAccess该类的实例.实际上,您的依赖项是碰巧具有相同公共接口的任何对象.通过要求上课,你暗示你需要一个特定的实现,这是一个谎言.如果你已经正确设计了它,你只关心接口是否相同,所以通过只询问接口本身,你准确指定了你要指定的意思:)
| 归档时间: |
|
| 查看次数: |
6408 次 |
| 最近记录: |