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 selects
terhadap 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 DataSet
dari 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?
Jawaban:
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.sumber
BusinessObject bo = DAL.LoadRecord(id);
- kedengarannya benar? Logika untuk memetakan kueri ke BO itu sendiri akan terkandung dalam DAL, dan hanya di sana.Get
bukannyaLoad
, sepertiCustomer c = DAL.GetCustomer(id);
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.
sumber
ExecuteScalar
permintaan untuk mengembalikan nilai yang lebih masuk akal ke lapisan bisnis, sepertibool
? Saya pikir sebaliknya, ini adalah jawaban yang sangat mirip dengan jawaban Rachel.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.
sumber
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.
sumber