Objek Bisnis dalam Lapisan Akses Data


12

Jadi saya telah membuat lapisan akses data melalui TDD dan telah mendekati sedikit masalah. Saya lebih suka tidak memulai jalan yang salah, jadi saya pikir saya akan meminta kalian untuk melihat apakah pikiran saya sejalan dengan arsitektur yang bersih.

Metode dalam Lapisan Akses Data saya (DAL singkatnya), cukup sederhana. Mereka sejalan dengan prosedur yang tersimpan dalam database (tidak ada cara lain untuk memanggilnya untuk menjaga hal-hal tetap bersih), dan mereka mengandung parameter yang sama dengan prosedur yang dilakukan. Mereka kemudian hanya terhubung ke database, dan mengembalikan hasil permintaan. Ini salah satu contohnya:

public int DeleteRecord(int recordId)
{
    recordId.RequireThat("recordId").NotZeroOrLess();

    List<SqlParameter> parameters = new List<SqlParameter>();
    parameters.Add(new SqlParameter { ParameterName = "@RecordId", SqlDbType = SqlDbType.Int, Direction = ParameterDirection.Input, Value = recordId});

    return this.ExecuteNonQuery("DeleteRecord", parameters.ToArray());
}

Ini berfungsi sempurna untuk jenis metode ini karena saya tidak melakukan sesuatu yang berarti dengan hasil yang ditetapkan. Saya hanya ingin memastikan perintah itu berfungsi, jadi saya akan mengembalikan hasil dari non-query, yang hanya baris yang terpengaruh, dan saya dapat memverifikasi logika menggunakan nomor itu.

Namun, katakan dalam metode DAL lain, saya ingin memuat catatan. Prosedur pemuatan saya akan dieksekusi selectsterhadap sekelompok tabel dan mengembalikan DataSet, tetapi saya berjuang dengan apakah DAL saya harus membuat Objek Bisnis dalam metode menggunakan DataSet, atau jika Objek Bisnis saya sendiri hanya harus memiliki Load()metode yang mendapatkan DataSetdari DAL, dan kemudian pada dasarnya mengisi sendiri

Melakukannya melalui DAL akan menghasilkan lebih sedikit logika dalam Objek Bisnis (meskipun ini hanya pilih logika, itu masih logis), tetapi akan memadatkan DAL sedikit dan membuatnya merasa seolah-olah benar-benar melakukan sesuatu yang seharusnya tidak boleh dilakukan. ' t sedang melakukan.

apa yang kalian pikirkan?


Mengapa Anda tidak menggunakan Entity Framework?
jfrankcarr

@ jfrankcarr - Sejujurnya, terutama karena saya tidak begitu mengenalnya sebagaimana mestinya. Namun saya perlu mengolah ulang tabel saya dan menambahkan kunci asing yang tepat, dll. Sehingga Kerangka Entitas akan mengenali hubungan dengan benar. Hanya karena penasaran, jika saya menggunakannya, apakah saya akan melakukan semua pemilihan menggunakan kerangka kerja dengan Business Objects sendiri, atau apakah masih ada keputusan tentang di mana harus menempatkan pertanyaan LINQ itu?

Saya merekomendasikan meluangkan waktu untuk belajar EF. Pada awalnya, ini bisa terasa sedikit menakutkan, terutama ketika mencoba membuatnya sesuai dengan database yang sudah ada yang memiliki beberapa masalah desain yang sudah ada sebelumnya, tetapi itu sepadan.
jfrankcarr

Anda juga dapat melihat NHibernate jika Anda ingin melihat opsi lain.
Don 01001100

@ jfrankcarr - Saya pasti akan memeriksanya, tetapi bagaimana itu cocok dengan aplikasi akses data multi-tier? Apakah kerangka kerja entitas itu sendiri diimplementasikan dalam DAL itu sendiri, atau dalam lapisan lain atau bahkan Obyek Bisnis itu sendiri?

Jawaban:


4

DAL Anda harus mengembalikan objek data Anda

Idealnya DAL Anda harus menjadi objek "kotak hitam", yang dapat digunakan kode aplikasi Anda untuk meminta objek data atau memanipulasi objek data yang ada. Kadang-kadang ada lapisan lain yang diletakkan antara DAL dan kode aplikasi yang disebut Repository, yang selanjutnya memisahkan dua lapisan, meskipun ini tidak selalu diperlukan.

Selain itu, Anda biasanya tidak ingin objek bisnis Anda dapat dibuat sendiri. Ini dapat menyebabkan lubang keamanan di mana seseorang dapat menggunakan perpustakaan Anda, dan membuat instance baru dari objek Anda dengan memanggilnya .Load(someId), dan menggabungkan dua lapisan yang harus sepenuhnya terpisah.

Saya juga tidak menyarankan menyediakan .Load(DataSet ds)metode karena jika kumpulan data berubah, Anda harus memburu objek data yang menggunakan kumpulan data itu dan mengubahnya. Lebih mudah menyimpan semua kode akses data Anda di satu tempat, jadi jika Anda mengubah kueri akses data, Anda hanya perlu mengubah layer DAL Anda.


Tidak yakin bagaimana satu lapisan dapat diandalkan untuk "mengembalikan objek yang benar" jika definisi "objek yang benar" disimpan di lapisan lain.
TMN

@ TMN Itu kata-kata buruk. Saya mengubah kata-katanya sedikit karena Anda benar, kode aplikasi harus tahu objek apa yang diminta.
Rachel

@Rachel - Gotcha. Jadi, Anda akan merekomendasikan agar DAL mengembalikan instance dari apa pun Obyek Bisnis saya itu sendiri, benar? Saya agak bingung dengan kata-kata Anda tentang "objek data", tapi saya pikir saya memahaminya. Dengan begitu, kode saya dapat meminta Obyek Bisnis dari mana pun dibutuhkan (bukan melalui mereka sendiri), hanya dengan menelepon BusinessObject bo = DAL.LoadRecord(id);- kedengarannya benar? Logika untuk memetakan kueri ke BO itu sendiri akan terkandung dalam DAL, dan hanya di sana.

1
@Scott Itu benar, meskipun saya akan memberi nama metode DAL sesuatu seperti Getbukannya Load, sepertiCustomer c = DAL.GetCustomer(id);
Rachel

2

Metode saya, bahkan sebelum LINQ-To-SQL dan Entity Framework, adalah memiliki antarmuka dan perpustakaan kelas abstrak yang menyediakan "kontrak tertulis" untuk komunikasi antara berbagai lapisan aplikasi. Ini kadang-kadang disebut ontologi , definisi untuk domain kerja. Apa pun yang lewat di antara lapisan menggunakan 'kontrak' ini.

Saya tidak suka gagasan untuk melewatkan objek Dataset mentah dari lapisan data ke lapisan bisnis. Saya telah melihat hasil ini dalam sejumlah masalah, terutama ketika mengintegrasikan sumber data lama. Hal ini juga dapat mempersulit orang baru yang datang ke proyek untuk memahami dari mana data berasal. Terakhir, ini membutuhkan lapisan bisnis Anda dalam bisnis penanganan data langsung dari DB, yang dapat menyebabkan komplikasi di kemudian hari.

Contoh kode yang Anda miliki terlihat mirip dengan kode yang saya miliki sebelum LINQ. Saya memiliki kelas fungsi DB umum yang saya gunakan di dalam objek DAL saya. Kelas-kelas DAL akan membaca data dan memasukkannya ke dalam objek 'kontrak'. Hasil skalar, seperti contoh hapus Anda, akan mengembalikan nilai, biasanya boolean.


1
"Aku tidak suka gagasan untuk melewatkan objek Dataset mentah dari lapisan data ke lapisan bisnis." Ini. Seribu kali, ini.
Joshua Smith

@ jfrankcarr - DAL saya sebenarnya mengimplementasikan antarmuka, dan saya berencana memiliki antarmuka untuk semua yang mentransfer data dari lapisan ke lapisan, jadi saya pikir ide pola kami cocok di sana. Jadi, apakah Anda merekomendasikan saya mengubah metode yang mengembalikan hasil langsung dari ExecuteScalarpermintaan untuk mengembalikan nilai yang lebih masuk akal ke lapisan bisnis, seperti bool? Saya pikir sebaliknya, ini adalah jawaban yang sangat mirip dengan jawaban Rachel.

Saya biasanya mengembalikan boolean untuk membuat / memperbarui / menghapus panggilan kecuali saya membutuhkan jumlah catatan yang terpengaruh. Sebagai contoh, saya mungkin mengembalikan int jika proc yang disimpan sedang memproses beberapa baris pesanan atau sesuatu seperti itu.
jfrankcarr

0

DAL Anda harus mengembalikan Dataset. Dataset yang dikembalikan harus menjadi objek bisnis, seharusnya tidak ada yang perlu Anda lakukan selain memeriksa bahwa ia memiliki data yang diharapkan. Jika Anda perlu berbuat lebih banyak dengan itu maka Anda mencoba melakukan terlalu banyak dalam satu prosedur tersimpan atau tidak mengembalikan data dengan benar dalam prosedur tersimpan.


0

Saya akan merekomendasikan objek bisnis Anda memiliki konstruktor untuk mengisi sendiri dari set hasil. Ini menghapus sambungan antara DAL Anda dan lapisan bisnis. Jika Anda ingin mengisolasi keduanya secara menyeluruh, buat peta sederhana pasangan nama => nilai dari set hasil Anda dan meneruskannya ke konstruktor.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.