Pemisahan pengambilan data dan objek bisnis antara DAL dan BLL Layers

9

Saya melakukan riset sebelum memposting pertanyaan ini. Di antara pertanyaan atau posting lainnya, salah satunya disediakan di bawah ini. Saya tidak bisa mendapatkan pikiran yang jernih bagaimana menentukan ..

Objek Bisnis dalam Lapisan Akses Data

Saya memiliki Repositori dan Business Layers memanggil repositori untuk mengambil data. Misalnya, katakan saya memiliki kelas berikut untuk BLL dan 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; }
}

Jika BLL ingin mengambil objek Pelanggan, itu akan memanggil GetCustomerById (customerId) di DAL.

Berikut ini adalah kekhawatiran saya, saya tidak bisa mendapatkan pikiran yang jernih:

  1. Saya tidak bisa melihat cara menentukan objek yang harus dikembalikan oleh GetCustomerById di DAL? Haruskah mengembalikan BllCustomer atau DalCustomer?

  2. Di mana seharusnya mengambil (dan / atau mengonversi ke objek Bisnis) dari alamat yang terkait dengan pelanggan?

Jika DAL mengembalikan objek Dal maka, logika untuk mengambil dan mengisi Alamat hanya bisa di BLL. Jika DAL mengembalikan objek BLL, maka logika untuk mengambil dan mengisi Alamat dapat berupa BLL atau DAL. Saat ini DAL mengembalikan Objek Bisnis dan logika untuk mengisinya adalah dalam DAL.

Dari apa yang saya baca, saya kira tidak ada benar atau salah. Dari tautan yang disertakan di atas, ada orang yang mengatakan satu arah dan yang lain mengatakan sebaliknya. Tetapi bagaimana saya menentukan mana yang paling cocok untuk kasus saya?

Bantuan apa pun akan dihargai.

ShamirDaj
sumber
2
Pertanyaan pertama saya adalah: apakah ini aplikasi warisan? Ada banyak Kerangka ORM di luar sana yang membuat kode semacam ini menjadi usang dan saya akan mendorong Anda untuk mempertimbangkan kerangka kerja seperti itu ...
JDT
@ JDT Saya tidak yakin apa yang Anda maksud, saya menggunakan Entity Framework dan memiliki masalah yang sama persis. Seperti yang saya pahami, Anda tidak seharusnya menggunakan ORM Anda sebagai objek domain, jadi di mana terjemahan itu dibuat?
pseudocoder
Mengapa kerangka kerja ORM Anda tidak mengembalikan objek yang juga merupakan objek domain?
JDT
3
@JDT ORM (EF dalam kasus ini) mengembalikan kelas entitas yang mewakili, biasanya, satu tabel database per kelas. Ini biasanya mirip dengan, tetapi tidak harus sama dengan, kelas domain. Mungkin Anda hanya mengatakan bahwa boleh saja menggunakan kelas ORM sebagai kelas domain? Saya telah membaca di sejumlah tempat bahwa ini adalah tidak-tidak.
pseudocoder

Jawaban:

5

Saya tidak bisa melihat cara menentukan objek yang harus dikembalikan oleh GetCustomerById di DAL? Haruskah mengembalikan BllCustomer atau DalCustomer?

Seharusnya mengembalikan objek DalCustomer , mengembalikan objek BllCustomer akan melanggar prinsip tanggung jawab tunggal . Anda dapat melihat objek DalCustomer sebagai antarmuka atau kontrak yang dikonsumsi oleh lapisan bisnis (atau konsumen). Akibatnya jika mengembalikan BllCustomer , DAL harus melayani setiap objek lapisan bisnis yang memanggilnya atau berpotensi menyebutnya.

Di mana seharusnya mengambil (dan / atau mengonversi ke objek Bisnis) dari alamat yang terkait dengan pelanggan?

Konversi harus dilakukan dalam model tampilan atau manajer. Anda harus memiliki perantara untuk memanggil layanan Anda atau komponen akses data. Jika Anda merasa perlu, Anda dapat memiliki konversi di objek BllCustomer Anda . Tetapi kemudian ketika Anda menukar DAL Anda dari MSSQL ke Oracle misalnya objek Anda kembali (atau antarmuka) harus tetap sama.

Lebih disukai lapisan bisnis Anda juga harus independen dari Lapisan Data Anda. Lapisan Bisnis bertanggung jawab atas aturan bisnis Anda. Di sinilah Anda akan menambahkan validasi Anda menggunakan kerangka validasi untuk menegakkan aturan bisnis Anda.

Derika
sumber
4

Repositori Anda harus mengembalikan objek BLL atau domain. kemungkinan Anda tidak membutuhkan objek DAL sama sekali.

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"]);
    }
}
Ewan
sumber
Haruskah BLL atau perpustakaan kelas terpisah mengekspos antarmuka bukan kelas konkret suka Customer?
Yola
1
Tidak apa-apa untuk mengekspos kelas konkret. Antarmuka untuk repositori akan berguna
Ewan
3

Biasanya, DAL tidak memiliki pengetahuan tentang BLL. Pikirkan seperti ini, aplikasi yang berbeda dengan BLL yang berbeda dapat menggunakan DAL yang sama. Aplikasi / modul Hutang dan aplikasi Piutang untuk perusahaan yang sama akan membagikan data (klien, biaya, pembayaran, dll.). Mencoba memiliki satu DLL yang memiliki pengetahuan lebih dari satu BLL akan sangat sulit dan tidak perlu. Ini juga akan memungkinkan Anda untuk mengubah penyimpanan data Anda tanpa dampak pada BLL (selama Anda tidak merusak antarmuka).

Anda sekarang bisa meneruskan objek DAL ke BLL atau Anda bisa membuat set objek ketiga: Entity. Ini akan berisi hanya nilai-nilai yang akan diedarkan bersama. DAL akan mereferensikan entitas dan berinteraksi dengan penyimpanan / database Anda dan BLL akan menangani semua logika dan referensi 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
}
JeffO
sumber
Terima kasih atas komentarmu. Saya setuju dengan Anda .. Saya sudah dapat melihat bahwa DAL / (Repositori) kami sudah diisi dengan logika seperti jika jenisnya adalah A, lalu pergi mengambil data dari tabel B, tetapi jika jenisnya adalah C, kemudian pergi mengambil data dari tabel C. Tapi saya bingung dengan contoh Anda menggunakan EntCustomer. Dalam kasus saya, DalCustomer adalah mirror dari tabel di DB. Bisakah Anda memberikan lebih banyak contoh, bagaimana EntCustomer digunakan atau mengapa saya harus menggunakannya dan memanfaatkannya. Saya sedang berpikir untuk mengubah DAL untuk mengembalikan DalObjects ke BLL. Bll akan menggantung konversi ke Business Objs, mengambil dan mengisi objek yang disarangkan.
ShamirDaj
Bisakah Anda memberikan lebih banyak umpan balik?
ShamirDaj
Saya berpikir bahwa tujuan dari Ent-objek adalah hanya mentransfer data antara DAL dan BLL. Kelas-kelas DAL Anda dapat terus mencerminkan struktur db, tetapi kelas-kelas itu akan menjadi internal ke DAL. Ketika BLL meminta data dari DAL, DAL akan mengambil objek-DAL yang diperlukan dari database (dalcustomer + daladdress) dan membangun sebuah instance dari EntCustomer dari mereka dan mengembalikannya ke BLL.
artokai
-1

DAL harus independen dari BL dan BL bergantung pada DAL. UI Anda seharusnya hanya Mengakses data melalui BL. Praktik yang baik jika Anda mengembalikan DataTable atau DataRow dari DAL dan lalu Konversikan DataTable / DataRow menjadi objek BL. Saat UI Anda perlu mengakses data, ia dapat mengakses dari BL. Jadi UI akan independen dari nama kolom dan tipe Database (SQL Server, Oracle ..). Dengan cara ini UI Anda akan sepenuhnya bebas dari DAL. Secara pribadi saya lebih suka nama kelas seperti "CustomerBL", Jangan gunakan kata BL dalam mengemis nama kelas.

Di bawah ini lihat Contoh Kode.

//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;
    }
}
Jigneshk
sumber
Err ... Bukankah itu berarti BLL Anda perlu memiliki pengetahuan tentang format / struktur tabel data Anda? ...
Paul