Saya percaya bahwa jika Anda memiliki repositori Anda menggunakan ORM yang sudah cukup disarikan dari database.
Namun, di mana saya bekerja sekarang, seseorang percaya bahwa kita harus memiliki lapisan yang mengabstraksi ORM jika kita ingin mengubah ORM nanti.
Apakah ini benar-benar diperlukan atau itu hanya banyak over head untuk membuat layer yang akan berfungsi pada banyak ORM?
Edit
Hanya untuk memberikan lebih banyak detail:
- Kami memiliki kelas POCO dan Kelas Entitas yang dipetakan dengan AutoMapper. Kelas entitas digunakan oleh lapisan Repositori. Lapisan repositori kemudian menggunakan lapisan abstraksi tambahan untuk berkomunikasi dengan Entity Framework.
- Lapisan bisnis sama sekali tidak memiliki akses langsung ke Entity Framework. Bahkan tanpa lapisan tambahan abstraksi atas ORM, yang satu ini perlu menggunakan lapisan layanan yang menggunakan lapisan repositori. Dalam kedua kasus, lapisan bisnis benar-benar terpisah dari ORM.
- Argumen utama adalah untuk dapat mengubah ORM di masa depan. Karena itu benar-benar terlokalisasi di dalam lapisan Repositori, bagi saya, sudah terpisah dengan baik dan saya tidak melihat mengapa lapisan tambahan abstraksi diperlukan untuk memiliki kode "kualitas".
Jawaban:
Dengan begitu terletak kegilaan. Sangat tidak mungkin Anda perlu mengubah ORM. Dan jika Anda pernah memutuskan untuk mengubah ORM, biaya penulisan ulang pemetaan akan menjadi sebagian kecil dari biaya untuk mengembangkan dan mempertahankan meta-ORM Anda sendiri. Saya berharap Anda dapat menulis beberapa skrip untuk melakukan 95% dari pekerjaan yang diperlukan untuk mengganti ORM.
Kerangka kerja internal hampir selalu merupakan bencana. Membangun satu untuk mengantisipasi kebutuhan di masa depan hampir merupakan bencana yang dijamin. Kerangka kerja yang sukses diambil dari proyek-proyek yang sukses, tidak dibangun sebelumnya untuk memenuhi kebutuhan imajiner.
sumber
ORM menyediakan abstraksi untuk lapisan data Anda agar tidak tergantung pada RDBMS-nya, tetapi mungkin tidak cukup untuk "melepaskan" lapisan bisnis Anda dari lapisan data Anda. Khususnya, Anda tidak boleh membiarkan objek yang memetakan ke tabel RDBMS untuk "bocor" langsung ke lapisan bisnis.
Paling tidak, lapisan bisnis Anda perlu memprogram untuk antarmuka yang dapat dikelola oleh ORM, objek yang dipetakan tabel dari lapisan data yang berpotensi diimplementasikan. Selain itu, Anda mungkin perlu membuat lapisan berbasis permintaan abstrak bangunan untuk menyembunyikan kemampuan query asli ORM Anda. Tujuan utamanya adalah untuk menghindari "memasukkan" ORM tertentu ke dalam solusi Anda di luar lapisan datanya. Misalnya, mungkin tergoda untuk membuat string HQL ( Hibernate Query Language ) di lapisan bisnis. Namun, keputusan yang tampaknya tidak bersalah ini akan mengikat lapisan bisnis Anda ke Hibernate, sehingga memadukan lapisan bisnis dan akses data; Anda harus berusaha menghindari situasi ini sebanyak mungkin.
EDIT: Dalam kasus Anda, lapisan tambahan di dalam repositori adalah buang-buang waktu: berdasarkan poin nomor dua Anda, lapisan bisnis Anda cukup terisolasi dari repositori Anda. Memberikan isolasi tambahan akan menimbulkan kompleksitas yang tidak perlu, tanpa manfaat tambahan.
Masalah dengan membangun lapisan abstraksi ekstra di dalam repositori Anda adalah bahwa "merek" ORM menentukan cara Anda berinteraksi dengannya. Jika Anda membuat pembungkus tipis yang terlihat seperti ORM Anda, tetapi berada di bawah kendali Anda, mengganti ORM yang mendasarinya akan kira-kira sama sulitnya dengan tanpa lapisan tambahan itu. Jika, di sisi lain, Anda membangun lapisan yang tidak terlihat seperti ORM Anda, maka Anda harus mempertanyakan pilihan Anda atas teknologi pemetaan objek-relasional.
sumber
UnitOfWork biasanya menyediakan abstraksi ini. Ini adalah satu tempat yang perlu diubah, repositori Anda bergantung padanya melalui Antarmuka. Jika Anda perlu mengubah O / RM, cukup terapkan UoW baru di atasnya. Satu dan selesai.
BTW melampaui hanya beralih O / RM, pikirkan pengujian unit. Saya memiliki tiga implementasi UnitOfWork, satu untuk EF, satu untuk NH (karena saya sebenarnya DID harus mengganti proyek tengah O / RM untuk klien yang menginginkan dukungan Oracle), dan satu untuk ketekunan InMemory. Kegigihan InMemory sempurna untuk pengujian unit atau bahkan untuk prototyping cepat sebelum saya siap untuk meletakkan database di belakangnya.
Kerangka kerja ini sederhana untuk diterapkan. Pertama, Anda memiliki antarmuka IRepository generik
Dan antarmuka IUnitOfWork
Berikutnya adalah repositori dasar (pilihan Anda apakah itu abstrak atau tidak
Menerapkan IUnitOfWork adalah permainan anak-anak untuk EF, NH, dan In Memory. Alasan saya mengembalikan IQueryable, adalah untuk alasan yang sama, Ayende disebutkan dalam posnya, klien dapat memfilter lebih lanjut, mengurutkan, mengelompokkan, dan bahkan memproyeksikan hasilnya menggunakan LINQ dan Anda masih mendapatkan manfaat dari semuanya yang dilakukan di sisi server.
sumber