Bagaimana saya harus menerapkan pola repositori untuk model objek yang kompleks?

21

Model data kami memiliki hampir 200 kelas yang dapat dipisahkan menjadi sekitar selusin area fungsional. Akan menyenangkan menggunakan domain, tetapi pemisahannya tidak begitu bersih dan kami tidak dapat mengubahnya.

Kami mendesain ulang DAL kami untuk menggunakan Entity Framework dan sebagian besar rekomendasi yang saya lihat menyarankan menggunakan pola Repositori. Namun, tidak ada sampel yang benar-benar berurusan dengan model objek yang kompleks. Beberapa implementasi yang saya temukan menyarankan penggunaan repositori-per-entitas. Ini tampak konyol dan tidak dapat dipelihara untuk model yang besar dan kompleks.

Apakah benar-benar perlu untuk membuat UnitOfWork untuk setiap operasi, dan Repositori untuk setiap entitas? Saya bisa berakhir dengan ribuan kelas. Saya tahu ini tidak masuk akal, tetapi saya menemukan sangat sedikit panduan yang menerapkan Kerangka Kerja Repositori, Unit Kerja, dan Entitas atas model yang kompleks dan aplikasi bisnis yang realistis.

Eric Falsken
sumber

Jawaban:

6

Pertama, Anda akan menjalankan semua entitas yang Anda miliki dan bertanya pada diri sendiri:

Apakah masuk akal untuk bertahan entitas ini sendirian?

Maksud saya di sini, adalah bahwa dalam model objek Anda, beberapa entitas kemungkinan terkandung dalam entitas lain dalam hubungan master-detail. Jika entitas Anda sangat bergantung pada yang lain, jangan buat repositori untuk entitas ini sendirian karena kemungkinan tidak akan bertahan dengan sendirinya. Sebagai gantinya, Anda akan membuat repositori untuk setiap kelas induk, dan Anda akan memastikan bahwa entitas anak dan relasi lainnya tetap ada pada saat yang sama.

Saya tidak suka bagaimana mereka menerapkan pola UnitOfWork di tautan yang Anda berikan. Saya sarankan Anda untuk melakukan sesuatu yang lebih sejalan . Anda tidak perlu mendefinisikan satu kelas per repositori. Kelas yang sama dapat digunakan untuk setiap repositori, masing-masing memiliki turunannya sendiri dari kelas UnitOfWork selama masa operasi. Anda juga dapat menggunakan kembali UnitOfWork yang sama di repositori berbeda untuk perubahan yang ingin Anda lakukan secara bersamaan.

marco-fiset
sumber
Tautan yang bagus! Saya memeriksanya.
Eric Falsken
Tautan Anda (dan jawaban) adalah yang paling membantu meskipun saya akhirnya tidak menggunakan pola yang disediakan. Saya akhirnya menggunakan kelas pembungkus yang memproksi metode Add / Attach / Remove / SaveChanges untuk berfungsi sebagai repositori umum, dan kemudian menambahkan metode Query / QuerySingle / QueryAll yang menerima kelas kueri kustom untuk menahan implementasi kueri saya. Ini bekerja dengan baik sehingga saya bisa melakukan query LINQ dan T-SQL tanpa melibatkan EF secara langsung.
Eric Falsken
Kerangka Entitas, dengan penggunaan transaksi, sudah merupakan implementasi dari pola Unit Kerja.
Greg Burghardt
1
tautan sudah mati ...
Newtopian
3

Mungkin Anda harus melihat di Domain-Driven Design . Ini merekomendasikan pengelompokan objek Anda di Agregat dan membuat repositori hanya untuk entitas Root dari setiap Agregat. Ini adalah cara yang bagus untuk menertibkan model objek besar yang kompleks.

Area fungsional Anda yang berbeda dapat menjadi Konteks Terbatas . Ada berbagai teknik untuk menangani Bounded Contexts yang tumpang tindih jika pemisahan keduanya tidak jelas.

guillaume31
sumber
0

Apa landasan teori yang Anda temukan untuk desain basis data "Pola penyimpanan"? Saya kira tidak ada. Ini adalah lapisan kerumitan yang bertumpu pada premis palsu: bahwa "lapisan kegigihan" adalah sesuatu yang harus diisolasi. Dari apa yang bisa saya katakan, ini memainkan ke ketidaktahuan pemrograman yang luas tentang prinsip-prinsip desain relasional, dan panders ke sentralitas yang disyaratkan dari desain OO aplikasi. Tapi itu tidak membenarkan keberadaannya dengan alasan yang rasional, apalagi teoretis.

One True Path ke desain basis data tidak berubah dalam 30 tahun: menganalisis data. Temukan kunci dan batasan dan hubungan banyak ke satu. Desain tabel Anda sesuai dengan bentuk normal Boyce-Codd. Gunakan tampilan dan prosedur tersimpan untuk memfasilitasi akses data.

Meskipun tidak dicintai, SQL DBMS menyediakan lapisan isolasi yang lebih baik daripada apa pun yang bisa diberikan oleh programmer. Memang benar bahwa ketika database berubah, SQL yang digunakan untuk mengaksesnya mungkin harus berubah. Tetapi perhatikan bahwa itu benar terlepas dari apakah ada lapisan mediasi atau tidak . Selama aplikasi menggunakan tampilan dan prosedur tersimpan untuk mengakses DBMS, alat rekayasa SQL biasa akan menunjukkan ketika perubahan pada basis data yang mendasari membatalkan pandangan dan prosedur tersimpan tersebut.

Disinilah letak tantangannya, tentu saja. Lapisan mediasi memberikan ilusi isolasi dan kenyamanan bagi programmer menulis kode, yang ia tahu bagaimana melakukannya. Mempelajari desain basis data dan SQL membutuhkan pembelajaran sesuatu yang baru. Kebanyakan orang lebih suka mati daripada berpikir, dan banyak yang berhasil.

Seseorang di tim Anda pasti akan keberatan bahwa menulis SQL untuk mendukung 200 kelas Anda banyak pekerjaan. Tanpa keraguan. Tapi setidaknya ini berguna . Jika Anda mendesain database dengan meniru desain OO Anda, Anda juga akan melakukan banyak pekerjaan, banyak yang tidak berguna, dan mengalahkan sebagian besar apa yang ditawarkan DBMS kepada Anda.

Sebagai contoh, Anda merenungkan Unit Kerja mencerminkan dalam database (seperti tabel atau tabel, saya kira). Unit kerja adalah built-in layanan DBMS: begin transaction... database update ... commit transaction. Tidak ada yang bisa dimodelkan, selain pemetaan kelas Anda ke tabel database di SQL.

Pertanyaan Anda telah diposting 4 tahun yang lalu. Saya menjawab karena "diperbarui" dalam beberapa cara baru-baru ini, menunjukkan masih menarik bagi seseorang. Saya harap jawaban saya mendorong pembaca untuk menerapkan teori relasional dasar untuk masalah daripada mengadopsi solusi yang tidak berguna.

James K. Lowden
sumber