7

以下のコードを参照してください。

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 オブジェクトを返します。これは正しいアプローチですか?つまり、永続クラスを特定し、データにアクセスして Person オブジェクトを返す関数を持つ対応する DAL クラスを作成しました。

この質問は「主観的」であるというコメントがあります。私はこれに賛同する。設計はプロジェクトの要件に依存することを認識しています。SOLID (単一責任など) などに似た DAL を設計するために文書化された原則はありますか?

4

1 に答える 1

6

はい、あなたの質問は、ロジックをレイヤーに分離する非常にクリーンな方法を示しています。PersonBLLクラスはビジネス レイヤーの一部になり、クラスPersonDALはデータ アクセス レイヤーの一部になり、Personクラスはデータ転送オブジェクト (DTO) レイヤーの一部になります。これは、レイヤーを分離するための非常に一般的な方法であり、多くの状況でうまく機能します。

私の唯一の推奨事項は次のとおりです。

  • 独自のクラス ライブラリ プロジェクトではない場合でも、各レイヤーを独自の名前空間に配置する必要があります。
  • ビジネス層からメッセージ ボックスを表示しないでください。デモンストレーションの手段としてこれを行っただけだと思いますが、念のため、言及する必要があると思いました。メッセージ ボックスの表示は、UI レイヤーの一部である必要があります。たとえばPersonBLL.getPersonByID、Windows サービスまたは Web サービスから呼び出している場合、メッセージ ボックスを表示することはまったく不適切です。
  • 通常、すべてのメソッドはキャメルケースではなくパスカルケースです。プライベート メソッドをキャメル ケースにすることを好む人もいますが、パブリック メソッドをキャメル ケースにするべきではないことは確かです。
  • 依存性注入手法 (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) インターフェイスとして要求することをお勧めします。そうするのは少し面倒かもしれませんが、すぐに慣れます。多くの場合、その時点でクラスごとに 1 つのインターフェイスを作成するため、クラスと同じコード ファイルにインターフェイスを配置すると便利です。したがって、たとえば、PersonBusiness.vb にはPersonDataAccessクラスとIPersonDataAccessインターフェイスの両方が含まれます。

依存関係にクラスではなくインターフェイスを使用することが重要な理由は 2 つあります。

  1. 設計が柔軟であることを保証します。あらゆる種類の具体的な実装を作成できるように、依存関係の型のすべてのパブリック メンバーをオーバーライドできるようにする必要があります。これを行う方法は他にもあります。たとえば、クラスIPersonDataAcess内のすべてのパブリック プロパティとメソッドを修飾子でマークするだけでインターフェイスの作成をスキップできますが、それを強制するものは何もありません。いつもそうするのを覚えていたとしても、あなたのコードで作業している他の誰かがそうすべきだと知っているとは限りません。PersonDataAccessOverrideable

    DI は、コードがテスト可能であることを確認するための最良のツールであるため、単体テストと結び付けられることがよくあります。単体テストでは、依存関係の型のメンバーをオーバーライドできることが特に重要です。これにより、単体テストを適切に実行するために必要な方法で機能する「偽の」オブジェクトを作成できます。これらの「偽の」オブジェクトはモックと呼ばれます。

  2. 依存関係が何であるかについて、より技術的に正直になります。PersonDataAccess実際には、依存関係が実際にクラスのインスタンスであると言っているわけではありません。実際には、依存関係は、たまたま同じパブリック インターフェイスを持つオブジェクトです。クラスを要求することで、特定の実装が必要であることを暗示していますが、これは嘘です。適切に設計した場合は、インターフェースが同じであることのみを気にするため、インターフェース自体のみを要求することで、指定する意味を正確に指定しています:)

于 2013-01-01T18:08:30.353 に答える