DALレイヤーとBLLレイヤー間でのデータとビジネスオブジェクトの取得の分離


9

この質問を投稿する前に、いくつか調査を行いました。他の質問や投稿の中で、そのうちの1つを以下に示します。どのように判断するか明確な心がつかめなかった。

データアクセス層内のビジネスオブジェクト

リポジトリがあり、ビジネスレイヤーはリポジトリを呼び出してデータを取得します。たとえば、BLLとDALの次のクラスがあるとします。

class BllCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}

class BllAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

class DalCustomer 
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public int AddressID {get; set;}
}

class DalAddress
{
     public int AddressId {get; set;}
     public String Street {get; set;}
     public String City {get; set;}
     public String ZipCode {get; set; }
}

BLLがCustomerオブジェクトを取得したい場合は、DALでGetCustomerById(customerId)を呼び出します。

以下は私が明確な心をつかむことができなかった私の懸念です:

  1. DALのGetCustomerByIdが返すオブジェクトを決定する方法がわかりません。BllCustomerまたはDalCustomerを返す必要がありますか?

  2. 顧客に関連付けられた住所の取得(および/またはビジネスオブジェクトへの変換)はどこにありますか?

DALがDalオブジェクトを返す場合、アドレスを取得して入力するロジックはBLLにのみ存在できます。DALがBLLオブジェクトを返す場合、アドレスを取得して入力するロジックは、BLLまたはDALのいずれかになります。現在、DALはビジネスオブジェクトを返し、それを埋めるロジックはDALにあります。

私が読んだことから、私は正しいか間違っていると思います。上記のリンクから、ある方法で他の人が言う方法があります。しかし、どの方法が私のケースに最適かを判断するにはどうすればよいですか?

任意の助けいただければ幸いです。


2
私の最初の質問は、これはレガシーアプリケーションですか?この種のコードを時代遅れにするORMフレームワークはたくさんあります。そのようなフレームワークを検討することをお勧めします...
JDT

@JDTどういう意味かわかりません。EntityFrameworkを使用していて、まったく同じ問題があります。私が理解しているように、ドメインオブジェクトとしてORMを使用することは想定されていないので、翻訳はどこで行われますか?
疑似

ORMフレームワークがドメインオブジェクトであるオブジェクトも返さないのはなぜですか?
JDT 2015年

3
@JDT ORM(この場合はEF)は、通常、クラスごとに1つのデータベーステーブルを表すエンティティクラスを返します。これは通常、ドメインクラスと似ていますが、必ずしも同じではありません。ORMクラスをドメインクラスとして使用しても問題ないと言っているだけでしょうか。私はこれがノーノーであることを多くの場所で読みました。
疑似コーダー

回答:


5

DALのGetCustomerByIdが返すオブジェクトを決定する方法がわかりません。BllCustomerまたはDalCustomerを返す必要がありますか?

それは返す必要がありDalCustomerの返却、オブジェクトをBllCustomerのオブジェクトが破壊される単一責任の原則を。DalCustomerオブジェクトは、ビジネスレイヤー(またはコンシューマー)が使用するインターフェイスまたはコントラクトとして表示できます。実際、BALCustomerを返した場合、DALは、それを呼び出す、または呼び出す可能性のあるすべてのビジネスレイヤーオブジェクトに対応する必要があります。

顧客に関連付けられた住所の取得(および/またはビジネスオブジェクトへの変換)はどこにありますか?

変換は、ビューモデルまたはマネージャーで行う必要があります。サービスまたはデータアクセスコンポーネントを呼び出すには、仲介者が必要です。必要に応じて、BllCustomerオブジェクトで変換を行うことができます。ただし、たとえば、DALをMSSQLからOracleに交換する場合、返されるオブジェクト(またはインターフェイス)は同じままである必要があります。

できれば、ビジネスレイヤーもデータレイヤーから独立している必要があります。ビジネス層は、ビジネスルールを担当します。ここに、検証フレームワークを使用して検証を追加し、ビジネスルールを適用します。


4

リポジトリはBLLまたはドメインオブジェクトを返す必要があります。おそらく、DALオブジェクトはまったく必要ありません。

public class Customer
{
    public string Name {get; private set;}
    public Customer(string name)
    {
        this.Name = name;
    }
}

public class Repository
{
    public Customer GetCustomer(string id)
    {
        //get data from db
        return new Customer(datarow["name"]);
    }
}

BLLまたは個別のクラスライブラリは、次のような具象クラスではなくインターフェイスを公開する必要がありますCustomerか?
Yola

1
いいえ。具象クラスを公開するのは問題ありません。リポジトリのインターフェースが役に立つでしょう
Ewan

3

通常、DALはBLLを認識していません。このように考えると、異なるBLLを持つ異なるアプリケーションが同じDALを使用する可能性があります。同じ会社のPayablesアプリケーション/モジュールとReceivablesアプリは、データ(クライアント、料金、支払いなど)を共有します。1つのDLLに複数のBLLの知識を持たせることは非常に困難であり、不必要です。これにより、BLLに影響を与えることなくデータストレージを変更することもできます(インターフェイスを壊さない限り)。

これで、DALオブジェクトをBLLに渡すことができます。または、3番目のオブジェクトセットであるエンティティを作成することもできます。これらには、一緒に渡される値のみが含まれます。DALはエンティティを参照し、ストレージ/データベースと対話し、BLLはすべてのロジックを処理してDALを参照します。

class EntCustomer
{
    public int CustomerId {get; set;}
    public String Name {get; set;}
    public BllAddress Address {get; set;}
}
class BllCustomer
{
   //reference EntCustomer, DalCustomer and handle business rules/logic
}

class DalCustomer 
{
   //reference EntCustomer and interact with data storage
}

コメントありがとうございます。私はあなたに同意します。タイプがAの場合のように、DAL /(Repository)がすでにロジックで満たされていることをすでに確認できます。次に、タイプBからデータを取得します。タイプがCの場合は、テーブルからデータを取得します。 C.しかし、私はEntCustomerを使用したあなたの例と混同しています。私の場合、DalCustomerはDBのテーブルのミラーです。EntCustomerがどのように使用されるのか、またはなぜそれを使用する必要があるのか​​、そしてその利点をさらに詳しく説明していただけますか?DALを変更してDalObjectsをBLLに返すことを考えています。BllはBusiness Objsへの変換を処理し、ネストされたobjを取得して入力します。
ShamirDaj 2014年

さらにフィードバックを提供できますか?
ShamirDaj 2014年

Entオブジェクトの目的は、DALとBLLの間でデータを転送することだけだと思います。DALクラスは引き続きdb構造をミラーリングできますが、それらのクラスはDALの内部にあります。BLLがDALからデータを要求すると、DALは必要なDALオブジェクトをデータベース(dalcustomer + daladdress)からフェッチし、それらからEntCustomerのインスタンスを作成してBLLに返します。
artokai 14年

-1

DALはBLから独立していて、BLはDALに依存している必要があります。UIはBL経由でのみデータにアクセスする必要があります。DALからDataTableまたはDataRowを返し、DataTable / DataRowをBLオブジェクトに変換する場合は、この方法をお勧めします。UIがBLからアクセスできるデータにアクセスする必要がある場合。したがって、UIは列名やデータベースタイプ(SQL Server、Oracleなど)から独立しています。このようにして、UIはDALから完全に独立します。個人的には、「CustomerBL」のようなクラス名が好きです。クラス名の最初にBLワードを使用しないでください。

以下はサンプルコードを参照してください。

//Customer Class
class BllCustomer
{
    public int CustomerId { get; set; }
    public String Name { get; set; }
    public BllAddress Address { get; set; }

    public static BllCustomer GetByCustomerId(int id)
    {
        DataRow dr = DalCustomer.GetByCustomerId(id);
        if (dr == null)
            return null;
        BllCustomer oCust = new BllCustomer();
        oCust.CustomerId = int.Parse(dr["CustomerId"].ToString());
        //Do for other class members and load values

        return oCust;
    }
}


class DalCustomer
{

    public static DataRow GetByCustomerId(int id)
    {
        //Get Data row from Database and return Datarow
        DataRow CustomerRow = GETFROMDATABASE("SELECT * from CUSTOMER");
        return CustomerRow;
    }
}

エラー...それは、BLLがデータテーブルの形式/構造の知識を持っている必要があるという意味ではないですか?...
Paul
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.