Pola Repositori vs DAL

93

Apakah mereka sama? Baru saja selesai menonton tutorial etalase Rob Connery dan mereka tampaknya teknik yang mirip. Maksud saya, ketika saya mengimplementasikan objek DAL saya memiliki metode GetStuff, Add / Delete dll dan saya selalu menulis antarmuka terlebih dahulu sehingga saya dapat beralih db nanti.

Apakah saya membingungkan?

Mike
sumber

Jawaban:

88

Anda pasti bukan orang yang membingungkan banyak hal. :-)

Saya pikir jawaban atas pertanyaan itu tergantung pada seberapa besar Anda ingin menjadi seorang purist.

Jika Anda menginginkan sudut pandang DDD yang ketat, itu akan membawa Anda ke satu jalur. Jika Anda melihat repositori sebagai pola yang telah membantu kami menstandarisasi antarmuka lapisan yang memisahkan antara layanan dan database, ini akan menurunkan Anda.

Repositori dari sudut pandang saya hanyalah lapisan akses data yang ditentukan dengan jelas, atau dengan kata lain cara standar untuk menerapkan Lapisan Akses Data Anda. Ada beberapa perbedaan antara implementasi repositori yang berbeda, tetapi konsepnya sama.

Beberapa orang akan menempatkan lebih banyak batasan DDD pada repositori sementara yang lain akan menggunakan repositori sebagai mediator yang nyaman antara database dan lapisan layanan. Repositori seperti DAL mengisolasi lapisan layanan dari spesifikasi akses data.

Salah satu masalah implementasi yang tampaknya membuatnya berbeda, adalah bahwa repositori sering dibuat dengan metode yang mengambil spesifikasi. Repositori akan mengembalikan data yang memenuhi spesifikasi tersebut. Kebanyakan DAL tradisional yang pernah saya lihat, akan memiliki kumpulan metode yang lebih besar di mana metode tersebut akan mengambil sejumlah parameter. Meskipun ini mungkin terdengar seperti perbedaan kecil, ini adalah masalah besar ketika Anda memasuki ranah Linq dan Ekspresi. Antarmuka repositori default kami terlihat seperti ini:

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

Apakah ini DAL atau repositori? Dalam hal ini saya rasa keduanya.

Kim

Kim Mayor
sumber
5
Terlambat ke pesta di sini, tapi kenapa T [], bukan List <T> (atau serupa)?
Mike Kingscott
27
Mungkin IEnumerable <T> akan menjadi yang terbaik.
Venemo
9
atau IQuerizable <T>
kenwarner
1
Saya pikir IQueryable <T> akan menjadi pilihan terbaik, karena memungkinkan Anda untuk merangkai metode dan menunda eksekusi sehingga database melakukan semua pekerjaan.
0lukasz0
4
@kenwarner Saya pikir mengembalikan IQuerizable <T> membocorkan abstraksi. Anda harus mengembalikan objek domain dari repositori Anda.
Matius
42

Repositori adalah pola yang dapat diterapkan dalam banyak cara berbeda, sedangkan lapisan akses data memiliki tanggung jawab yang sangat jelas: DAL harus tahu cara menyambung ke penyimpanan data Anda untuk melakukan operasi CRUD.

Repositori dapat berupa DAL, tetapi juga dapat berada di depan DAL dan bertindak sebagai jembatan antara lapisan objek bisnis dan lapisan data. Implementasi mana yang digunakan akan bervariasi dari proyek ke proyek.

Jeromy Irvine
sumber
23

Satu perbedaan besar adalah DAO adalah cara umum untuk menangani persistensi untuk entitas apa pun di domain Anda. Repositori di sisi lain hanya berurusan dengan akar agregat.

pondermatik
sumber
26
Hal pertama yang harus dipahami adalah bahwa repositori sebagai pola adalah bagian dari sistem yang lebih besar yang dikenal sebagai Desain Didorong Domain. Dalam objek domain DDD dikelompokkan menjadi agregat, masing-masing dengan akar agregat. Misalnya PurchaseOrder adalah akar agregat dan OrderItems adalah turunan dalam akar agregat. Repositori hanya menangani akar agregat. Artinya, OrderItem misalnya tidak pernah dimuat secara independen dari aggreate root-nya. Jadi, Anda tidak akan pernah memiliki repositori OrderItem di DDD. Namun, dalam sistem non-DDD Anda dapat memiliki OrderItemDao karena Dao tidak terbatas pada akar agregat.
pondermatic
NG, Terima kasih! Saya mulai melihatnya seperti itu, tetapi ini membuatnya jelas. Saya harus mulai membaca semua literatur DDD!
David
@bingle, deskripsi bagus tentang akar agregat dan bagaimana objek turunan dimuat oleh repositori. Di manakah repositori akan ada dalam aplikasi berlapis-lapis? Saya bisa melihatnya berada di pustaka lapisan akses data tetapi karena itu memuat objek anak, haruskah itu ada di pustaka lapisan logika sebagai gantinya? Naluri saya memberi tahu saya lapisan akses data tetapi saya ingin pendapat Anda tentang masalah ini.
Jeff LaFay
12

Saya sedang mencari jawaban untuk pertanyaan serupa dan setuju dengan dua jawaban peringkat tertinggi. Mencoba mengklarifikasi ini untuk diri saya sendiri, saya menemukan bahwa jika Spesifikasi, yang sejalan dengan pola Repositori, diimplementasikan sebagai anggota kelas satu model domain, maka saya dapat

  • menggunakan kembali definisi Spesifikasi dengan parameter berbeda,
  • memanipulasi parameter instance Spesifikasi yang ada (misalnya untuk mengkhususkan),
  • gabungkan mereka,
  • menjalankan logika bisnis pada mereka tanpa harus melakukan akses database apa pun,
  • dan, tentu saja, mengujinya secara independen dari implementasi Repositori yang sebenarnya.

Saya bahkan dapat melangkah lebih jauh dan menyatakan bahwa kecuali pola Repositori digunakan bersama dengan pola Spesifikasi, itu sebenarnya bukan "Repositori," tetapi DAL. Contoh yang dibuat-buat dalam pseudo-code:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

Lihat Fowler's Specification Essay untuk detailnya (itulah yang saya berdasarkan di atas).

Sebuah DAL akan memiliki metode khusus seperti

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

Anda dapat melihat bagaimana ini bisa dengan cepat menjadi tidak praktis, terutama karena Anda harus menentukan setiap antarmuka DAL / DAO dengan pendekatan ini dan menerapkan metode kueri DAL.

Dalam .NET, kueri LINQ dapat menjadi salah satu cara untuk mengimplementasikan spesifikasi, tetapi menggabungkan Spesifikasi (ekspresi) mungkin tidak semulus solusi yang dikembangkan sendiri. Beberapa ide untuk itu dijelaskan dalam Pertanyaan SO ini .

Thomas Jung
sumber
2

Pendapat pribadi saya adalah bahwa ini semua tentang pemetaan, lihat: http://www.martinfowler.com/eaaCatalog/repository.html . Jadi keluaran / masukan dari repositori adalah obyek domain, yang di DAL bisa apa saja. Bagi saya itu adalah tambahan / pembatasan penting, karena Anda dapat menambahkan implementasi repositori untuk database / layanan / apa pun dengan tata letak yang berbeda, dan Anda memiliki tempat yang jelas untuk berkonsentrasi melakukan pemetaan. Jika Anda tidak akan menggunakan batasan itu dan memiliki pemetaan di tempat lain, maka memiliki cara berbeda untuk merepresentasikan data dapat memengaruhi kode di tempat yang seharusnya tidak diubah.

eglasius.dll
sumber
1

Ini semua tentang interpretasi dan konteks. Mereka bisa sangat mirip atau memang sangat berbeda, tetapi selama solusinya berhasil, apa namanya!

c00ke
sumber
1

Repositori adalah sebuah pola, ini adalah cara untuk mengimplementasikan hal-hal dengan cara standar untuk menggunakan kembali kode yang kami bisa.

Xulfee
sumber
1

Keuntungan menggunakan pola repositori adalah untuk memalsukan lapisan akses data Anda, sehingga Anda dapat menguji kode lapisan bisnis Anda tanpa memanggil kode DAL. Ada keuntungan besar lainnya tetapi ini tampaknya sangat penting bagi saya.

Shailesh
sumber
1
Anda masih dapat membuat tiruan DAL, DAL tidak perlu berupa repositori. Poin pentingnya adalah bahwa strategi akses data apa pun yang Anda gunakan harus menerapkan antarmuka. Ini akan memungkinkan Anda untuk menggunakan wadah IoC serta menguji kode bisnis Anda dengan rapi tanpa memerlukan penyimpanan data.
cdaq
0

Dari apa yang saya pahami, pada dasarnya mereka bisa berarti hal yang sama - tetapi penamaan bervariasi berdasarkan konteks.

Misalnya, Anda mungkin memiliki kelas Dal / Dao yang mengimplementasikan antarmuka IRepository.

Dal / Dao adalah istilah lapisan data; tingkatan yang lebih tinggi dari aplikasi Anda berpikir dalam istilah Repositori.

remotefacade
sumber
0

Jadi dalam sebagian besar kasus (sederhana) DAO adalah implementasi Repository?

Sejauh yang saya pahami, tampaknya DAO secara tepat berhubungan dengan akses db (CRUD - Tidak ada pilihan ?!) sementara Repositori memungkinkan Anda untuk mengabstraksi seluruh akses data, mungkin menjadi fasad untuk beberapa DAO (mungkin sumber data yang berbeda).

Apakah saya di jalan yang benar?

Mike
sumber
Sebenarnya, saya akan membalikkannya dan mengatakan bahwa dari sudut pandang sederhana, Repositori adalah gaya implementasi tertentu untuk DAO, tapi ya, Anda berada di jalur yang benar. (R dari CRUD = Baca, jadi itu pilihan Anda.)
Jeromy Irvine
0

Di dunia luar (yaitu kode klien), repositori sama dengan DAL, kecuali:

(1) metode sisipkan / perbarui / hapus dibatasi untuk memiliki objek penampung data sebagai parameter.

(2) untuk operasi baca mungkin memerlukan spesifikasi sederhana seperti DAL (misalnya GetByPK) atau spesifikasi lanjutan.

Secara internal ia bekerja dengan Data Mapper Layer (misalnya konteks kerangka entitas, dll) untuk melakukan operasi CRUD yang sebenarnya.

Apa artinya pola Repositori: -

Juga, saya telah melihat orang sering bingung untuk memiliki metode Simpan terpisah sebagai implementasi sampel pola repositori selain metode Sisipkan / Perbarui / Hapus yang melakukan semua perubahan dalam memori yang dilakukan oleh metode sisipkan / perbarui / hapus ke database. Kita dapat memiliki metode Simpan pasti dalam repositori, tetapi itu bukan tanggung jawab repositori untuk mengisolasi CUD dalam memori (Buat, Perbarui, Hapus) dan metode persistensi (yang melakukan operasi tulis / ubah aktual dalam database), tetapi Tanggung jawab pola Satuan Kerja.

Semoga ini membantu!

Ashraf Alam
sumber
0

Seseorang dapat berargumen bahwa "repositori" adalah kelas tertentu dan "DAL" adalah seluruh lapisan yang terdiri dari repositori, DTO, kelas utilitas, dan apa pun yang diperlukan.

Jonathan Allen
sumber