2013-01-01 81 views
7

請參閱下面的代碼:打破BLL(業務邏輯層)到BLL和DAL(數據訪問層)

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 

PersonBLL調用PersonDAL並返回一個Person對象。這是正確的方法嗎?即我已經識別出一個持久類,並用一個函數來創建一個相應的DAL類,以訪問數據並返回Person對象。

有一條評論指出這個問題是「主觀的」。我同意這一點。我意識到設計取決於項目的要求。有沒有爲設計類似於SOLID(單一職責等)的DAL而記錄的原則等。

+0

「正確的方法」有點主觀。 「這是一種有效的方法嗎?」是可以回答的 - 我會說「是」。 – David

+0

@David Stratton,我已經更新了這個問題。你是否知道像設計數據訪問層特別相關的SOLID等原理? – w0051977

+0

很好的編輯。我會讓聰明的人比我回答這個問題。這不是我的專業領域,大多數人在這個網站上比我更聰明。我可能會誤導你。我所要提供的就是我之前看過這種設計,來自非.NET背景的人 - 這似乎很常見。我個人覺得這很乏味,但就像我說的,我不是這個街區最聰明的人。 – David

回答

6

是的,您的問題演示了一種非常乾淨的方法來將邏輯分爲多個層。 PersonBLL類將成爲業務層的一部分,PersonDAL類將成爲數據訪問層的一部分,Person類將成爲數據傳輸對象(DTO)層的一部分。這是分開你的圖層的一種非常常見的方式,在許多情況下都能很好地工作。

我唯一的建議是:

  • 你應該把每一層在自己的命名空間,如果還沒有自己的類庫項目。
  • 您不應該從業務層顯示消息框。我以爲你只是以此作爲示範的手段,但爲了以防萬一,我想我應該提及它。顯示消息框應該是UI層的一部分。例如,如果您從Windows服務或Web服務調用PersonBLL.getPersonByID,則顯示消息框完全不合適。
  • 通常,所有方法都是PascalCase,而不是camelCase。有些人更喜歡使用私人方法駱駝案件,但肯定公共方法不應該是駱駝案件。
  • 考慮使用依賴注入技術(DI)將數據訪問對象注入業務對象。

依賴注入

這裏有一個如何與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 

。你可以有多個可互換的數據訪問層實現,所以它更加靈活。此外,您可以在要單元測試業務類時注入虛假的數據訪問對象。 DI設計避免了導致越野車,意大利麪代碼的許多陷阱。

使用DI時,通常建議您要求依賴項對象作爲接口而不是具體類型(例如IPersonDataAccess而不是PersonDataAccess)。這樣做可能會有點麻煩,但你很快就會習慣。由於您經常在這一點上爲每個類創建一個接口,因此將接口放在與類相同的代碼文件中很方便。因此,例如,PersonBusiness.vb將包含PersonDataAccess類和IPersonDataAccess接口。

爲什麼有使用接口,而不是類,爲您的依賴兩方面的原因是很重要的:

  1. 它確保了設計靈活。您希望能夠覆蓋依賴類型的每個公共成員,以便您可以創建任何類型的具體實現。還有其他方法可以做到這一點。例如,您可以跳過創建IPersonDataAcess界面,方法是使用Overrideable修飾符簡單標記PersonDataAccess類中的每個公共屬性和方法,但沒有任何東西強迫您這樣做。即使你一直記得這樣做,這並不意味着別人在你的代碼上工作會知道他們應該這樣做。

    DI通常與單元測試捆綁在一起,因爲它是確保代碼可測試的最佳工具。在進行單元測試時,能夠以依賴類型覆蓋永遠的成員是非常重要的,所以你可以創建一個「假」對象,它可以按照你需要的方式工作,以便正確執行單元測試。這些「假」物體被稱爲模擬

  2. 你對技術上的依賴性更加誠實。實際上,你並不是說你的依賴實際上是類的一個實例。實際上,您的依賴關係是碰巧擁有相同公共接口的任何對象。通過請求課堂,你意味着你需要一個特定的實現,這是一個謊言。如果你設計得當,你只關心接口是相同的,所以通過只詢問接口本身,你正在明確地指定你的意思是什麼:)

+0

謝謝。 +1用於參考DI。你會爲所有類創建接口嗎? PersonDto在哪裏定義?我認爲它和我的Person類相同? – w0051977

+0

是的,我的例子中'PersonDto'被假定爲和你問題中的'Person'類相同。對困惑感到抱歉。是的,我會推薦爲所有非DTO類創建接口。如果你製作一個基本上只用於一個類的接口,我會建議把它和類放在同一個代碼文件中。因此,例如,PersonBusiness.vb將包含「PersonBusiness」類和「IPersonBusiness」接口。 –

+0

我喜歡將類文件和接口放在同一個文件中,因爲它會使項目變得粗糙。我不完全理解接口的好處。如果系統需要更改,那麼肯定需要更改 - 如果您有接口,則無關緊要,但無論我在網上看起來如何,似乎都暗示了它的作用。在我接受你的答案之前,你能舉個例子嗎?謝謝。 – w0051977