Mengapa memisahkan akses data?
Dari buku ini, saya pikir dua halaman pertama dari bab Model Driven Design memberikan beberapa alasan mengapa Anda ingin mengaburkan rincian implementasi teknis dari penerapan model domain.
- Anda ingin menjaga hubungan yang erat antara model domain dan kode
- Memisahkan masalah teknis membantu membuktikan model ini praktis untuk implementasi
- Anda ingin bahasa di mana-mana untuk menembus hingga ke desain sistem
Tampaknya ini semua untuk tujuan menghindari "model analisis" terpisah yang menjadi terpisah dari implementasi sistem yang sebenarnya.
Dari apa yang saya mengerti tentang buku ini, dikatakan "model analisis" ini dapat dirancang tanpa mempertimbangkan implementasi perangkat lunak. Setelah pengembang mencoba menerapkan model yang dipahami oleh sisi bisnis, mereka membentuk abstraksi mereka sendiri karena kebutuhan, menyebabkan dinding dalam komunikasi dan pemahaman.
Di arah lain, pengembang yang memperkenalkan terlalu banyak masalah teknis ke dalam model domain dapat menyebabkan kesenjangan ini juga.
Jadi Anda dapat mempertimbangkan bahwa mempraktikkan pemisahan masalah seperti kegigihan dapat membantu melindungi terhadap desain ini dan model analisis yang berbeda. Jika dirasa perlu untuk memperkenalkan hal-hal seperti ketekunan ke dalam model maka itu adalah bendera merah. Mungkin modelnya tidak praktis untuk implementasi.
Mengutip:
"Model tunggal mengurangi kemungkinan kesalahan, karena desain sekarang merupakan hasil langsung dari model yang dipertimbangkan dengan hati-hati. Desain, dan bahkan kode itu sendiri, memiliki komunikasi model."
Cara saya menafsirkan ini, jika Anda berakhir dengan lebih banyak baris kode berurusan dengan hal-hal seperti akses database, Anda kehilangan komunikasi itu.
Jika kebutuhan untuk mengakses database adalah untuk hal-hal seperti memeriksa keunikan, lihat:
Udi Dahan: kesalahan terbesar yang dilakukan tim saat menerapkan DDD
http://gojko.net/2010/06/11/udi-dahan-the-biggest-mistakes-teams-make-when-applying-ddd/
di bawah "Semua aturan tidak dibuat sama"
dan
Menggunakan Pola Model Domain
http://msdn.microsoft.com/en-us/magazine/ee236415.aspx#id0400119
di bawah "Skenario untuk Tidak Menggunakan Model Domain", yang menyentuh subjek yang sama.
Cara memisahkan akses data
Memuat data melalui antarmuka
"Lapisan akses data" telah diabstraksi melalui antarmuka, yang Anda panggil untuk mengambil data yang diperlukan:
var orderLines = OrderRepository.GetOrderLines(orderId);
foreach (var line in orderLines)
{
total += line.Price;
}
Pro: Antarmuka memisahkan kode pipa "akses data", memungkinkan Anda untuk tetap menulis tes. Akses data dapat ditangani berdasarkan kasus per kasus memungkinkan kinerja yang lebih baik daripada strategi generik.
Cons: Kode panggilan harus menganggap apa yang telah dimuat dan apa yang belum.
Katakanlah GetOrderLines mengembalikan objek OrderLine dengan properti ProductInfo nol karena alasan kinerja. Pengembang harus memiliki pengetahuan mendalam tentang kode di balik antarmuka.
Saya sudah mencoba metode ini di sistem nyata. Anda akhirnya mengubah ruang lingkup apa yang dimuat sepanjang waktu dalam upaya untuk memperbaiki masalah kinerja. Anda akhirnya mengintip di belakang antarmuka untuk melihat kode akses data untuk melihat apa yang sedang dan tidak dimuat.
Sekarang, pemisahan kekhawatiran harus memungkinkan pengembang untuk fokus pada satu aspek kode pada satu waktu, sebanyak mungkin. Teknik antarmuka menghapus BAGAIMANA data ini dimuat, tetapi tidak BAGAIMANA BANYAK data dimuat, KAPAN dimuat, dan DI MANA itu dimuat.
Kesimpulan: Pemisahan yang sangat rendah!
Pemuatan Malas
Data dimuat sesuai permintaan. Panggilan untuk memuat data disembunyikan di dalam objek grafik itu sendiri, di mana mengakses properti dapat menyebabkan kueri sql untuk dieksekusi sebelum mengembalikan hasilnya.
foreach (var line in order.OrderLines)
{
total += line.Price;
}
Pro: 'KAPAN, DI MANA, dan BAGAIMANA' dari akses data disembunyikan dari pengembang yang berfokus pada logika domain. Tidak ada kode dalam agregat yang berhubungan dengan memuat data. Jumlah data yang dimuat dapat menjadi jumlah persis yang dibutuhkan oleh kode.
Cons: Ketika Anda terkena masalah kinerja, sulit untuk memperbaiki ketika Anda memiliki solusi "satu ukuran cocok untuk semua" generik. Pemuatan malas dapat menyebabkan kinerja yang lebih buruk secara keseluruhan, dan menerapkan pemuatan malas mungkin sulit.
Role Interface / Eager Fetching
Setiap use case dibuat eksplisit melalui Role Interface yang diimplementasikan oleh kelas agregat, yang memungkinkan strategi pemuatan data ditangani per use case.
Strategi pengambilan mungkin terlihat seperti ini:
public class BillOrderFetchingStrategy : ILoadDataFor<IBillOrder, Order>
{
Order Load(string aggregateId)
{
var order = new Order();
order.Data = GetOrderLinesWithPrice(aggregateId);
return order;
}
}
Maka agregat Anda dapat terlihat seperti:
public class Order : IBillOrder
{
void BillOrder(BillOrderCommand command)
{
foreach (var line in this.Data.OrderLines)
{
total += line.Price;
}
etc...
}
}
Strategi BillOrderFetching digunakan untuk membangun agregat, dan kemudian agregat melakukan tugasnya.
Pros: Memungkinkan untuk kode khusus per kasus penggunaan, memungkinkan untuk kinerja yang optimal. Sejalan dengan Prinsip Segregasi Antarmuka . Tidak ada persyaratan kode yang rumit. Tes unit gabungan tidak harus meniru strategi pemuatan. Strategi pemuatan umum dapat digunakan untuk sebagian besar kasus (mis. Strategi "muat semua") dan strategi pemuatan khusus dapat diterapkan bila perlu.
Cons: Pengembang masih harus menyesuaikan / meninjau strategi pengambilan setelah mengubah kode domain.
Dengan pendekatan strategi pengambilan Anda mungkin masih menemukan diri Anda mengubah kode pengambilan kustom untuk perubahan aturan bisnis. Ini bukan pemisahan keprihatinan yang sempurna tetapi akan berakhir lebih dapat dipertahankan dan lebih baik daripada opsi pertama. Strategi pengambilan memang merangkum CARA, KAPAN dan DI MANA data dimuat. Ini memiliki pemisahan keprihatinan yang lebih baik, tanpa kehilangan fleksibilitas seperti satu ukuran cocok untuk semua pendekatan pemuatan malas.