Pertanyaan Pola Repositori Standarisasi metode


Semua saya mencoba mencari tahu definisi yang benar dari pola repositori.

Pemahaman asli saya adalah ini (sangat dungu)

  • Pisahkan Objek Bisnis Anda dari Objek Data Anda
  • Standarisasi metode akses di lapisan akses data.

Saya benar-benar telah melihat 2 penerapan yang berbeda, dan tidak ada contoh formal online, yang saya lihat tersimpan di buku.

Implementasi 1:

public Interface IRepository<T>{
      List<T> GetAll();
      void Create(T p);
      void Update(T p);
}


public interface IProductRepository: IRepository<Product> {
      //Extension methods if needed
       List<Product> GetProductsByCustomerID();
}

Implementasi 2:

public interface IProductRepository {
      List<Product> GetAllProducts();
      void CreateProduct(Product p);
      void UpdateProduct(Product p);
      List<Product> GetProductsByCustomerID();
}

Perhatikan yang pertama adalah Get / Update / GetAll generik, dll, yang kedua adalah lebih dari apa yang akan saya definisikan sebagai "DAO".

Keduanya berbagi ekstraksi dari entitas data Anda. Yang saya suka, tetapi saya bisa melakukan hal yang sama dengan DAO sederhana. Namun bagian kedua menstandarisasi operasi akses Saya melihat nilai dalam, jika Anda mengimplementasikan perusahaan ini orang luas akan dengan mudah mengetahui set metode akses untuk repositori Anda.

Apakah saya salah menganggap bahwa standardisasi akses ke data merupakan bagian integral dari pola ini? Jika keduanya benar mengapa orang memilih untuk melakukan implementasi 2?

Badak memiliki artikel bagus tentang implementasi 1, dan tentu saja MS memiliki samar-samar definisi dan contoh implementasi 2 adalah sini.


32
2018-04-21 15:29


asal


Jawaban:


Saya kedua kutipan Fowler yang dikutip oleh oded. Saya ingin menunjukkan bahwa dia mengatakan "collection-seperti"Antarmuka. Bagaimana Anda mengimplementasikan koleksi seperti antarmuka tentu terserah Anda, tetapi tidak dapat atau harus Anda mencoba untuk menyembunyikan fakta itu merupakan sumber data jauh. Karena itu berbeda secara signifikan dari koleksi di memori, yang tidak perlu menyiram perubahan pada penyimpanan data jarak jauh. Mekanisme pelacakan perubahan ORM Anda atau solusi roll-your-own Anda menentukan bagaimana transparansi ini dapat dilakukan ke pemanggil. Penghapusan biasanya perlu ditandai secara eksplisit, sisipan dapat ditemukan (persistensi oleh reachability) dan pembaruan kadang-kadang perlu ditandai secara eksplisit juga. Gabungkan ini dengan dependensi rumit dari akar agregat Anda dan Anda akan melihat itu tidak sangat koleksi seperti.

Tidak ada yang namanya "implementasi repositori kanonik".

Terjadi pertempuran terus-menerus di antara para penganjur kelas dasar repositori generik dan mereka yang lebih suka menerapkan masing-masing repositori sendiri. Meskipun penerapan generik menarik dalam skenario sederhana, Anda akan sangat sering menganggapnya sebagai abstraksi yang sangat bocor. Sebagai contoh, beberapa agregat Anda mungkin hanya soft-deleted (dapat distimkan melalui override metode virtual) sementara yang lain mungkin tidak mendukung operasi penghapusan sama sekali.

Pastikan Anda memahami implikasi dari setiap pendekatan sebelum memutuskan rute mana yang akan diambil. Greg Young memiliki posting yang bagus tentang keunggulan repositori generik.

http://codebetter.com/blogs/gregyoung/archive/2009/01/16/ddd-the-generic-repository.aspx


14
2018-04-27 12:28



Dari Martin Fowler "Pola Arsitektur Aplikasi Perusahaan", definisi Pola Repositori adalah:

Memediasi antara domain dan lapisan pemetaan data menggunakan antarmuka seperti koleksi untuk mengakses objek domain.

Jadi, kedua pendekatan itu benar.


7
2018-04-21 15:33



Saya penggemar besar dari pola repositori generik tapi saya pikir Anda harus sangat mempertimbangkan tidak langsung mewarisi dari antarmuka karena dapat menjadi batasan yang sangat besar terutama karena banyak kali kode untuk antarmuka generik akan sama yang dapat didefinisikan dalam kelas dasar abstrak yang Anda tidak akan lagi dapat memiliki lebih dari 1 repositori generik di dalam kelas.

Saya sarankan memiliki pelaksana IProductRepository Anda mengakses generik IRepository<Product> melalui delegasi dan menyuntikkannya melalui konstruktor sehingga Anda dapat menyusun kelas Anda yang mungkin banyak IRepositories dan mengelompokkannya di belakang satu antarmuka dengan cara yang masuk akal.

Saya menulis blog tentang topik ini sementara itu secara khusus referensi NHibernate pola ini dapat diterapkan untuk semua jenis repositori: Membuat Repositori NHiberate generik dan extensible umum versi 2


4
2018-04-21 17:23



Dengan diperkenalkannya LINQ di .NET, pola repositori generik menjadi lebih mudah untuk disadari:

public interface IRepository<T> : IQueryable<T>
{
    void Add(T item);
    void Remove(T item);
}

Untuk memenuhi syarat sebagai repositori, ia hanya perlu dapat mengakses data di toko yang mendasarinya (mudah disediakan oleh IQueryable) dan memodifikasi data yang ada.

Anda dapat memberikan ekstensi ke antarmuka dasar untuk menyediakan kait untuk perilaku yang lebih spesifik-entitas (seperti pengkabelan ke dalam panggilan prosedur yang tersimpan untuk repositori berbasis SQL), tetapi sebagian besar operasi dapat diselesaikan oleh antarmuka yang sederhana.


2
2018-04-27 12:13



Selain antarmuka repositori generik Anda (implementasi 1) dan variasi Anda pada repositori peran-spesifik (implementasi 2) Anda juga dapat mempertimbangkan repositori metode generik:

public interface IRepository
{
    void Save<ENTITY>(ENTITY entity) where ENTITY : DomainEntity;

    ENTITY Load<ENTITY>(Guid id) where ENTITY : DomainEntity;

    IQueryable<ENTITY> Query<ENTITY>() where ENTITY : DomainEntity;

    IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
        where ENTITY : DomainEntity;
}

Versi ketiga ini berasal blogpost ini oleh Jimmy Bogard, di mana ia juga mengungkapkan preferensi untuk antarmuka repositori generik. Saya biasanya mengikuti itu dengan baseclass repositori generik yang mengimplementasikan antarmuka ini; dengan cara itu, saya hanya harus menerapkan hal-hal yang berbeda untuk setiap entitas domain.


1
2018-04-27 13:57



Saya biasanya menggunakan repositori generik dengan komposisi alih-alih warisan. Itu memberi saya keuntungan dari implementasi generik, dengan kontrol metode mana yang diekspos.

Sesuatu seperti ini:

public Interface IRepository<T>{
  List<T> GetAll();
  void Create(T p);
  void Update(T p);
}


public interface IProductRepository {
  //Extension methods if needed
   List<Product> GetProductsByCustomerID();
   List<T> GetAll();
   void Create(T p);
   //Let assume here you should not be able to update the products
}

public ProductRepository : IProductRepository {
    private IRepository _repository;

    public ProductRepository(IRepository repository) {
        this._repository = repository;
    }

       List<T> GetAll() 
       {
            _repository.GetAll();
       }

       void Create(T p) 
       {
            _repository.Create(p);
       }

       List<Product> GetProductsByCustomerID() 
       {
          //..implementation goes here
       }
}

0
2017-11-25 12:26



Pola repositori adalah salah satu pola yang paling sering digunakan dalam pengembangan perangkat lunak. Banyak pos yang dapat ditandai sebagai jawaban atas pertanyaan Anda. Sesuatu yang saya ingin soroti adalah kenyataan bahwa implementasi repositori yang baik akan ditingkatkan jika Anda menggunakan IoC (Autofac, Windsor, dll ...). Saya telah bermain lama dengan beberapa kerangka kerja berbasis ADO.NET (LinqToSql, EF) dan NHibernate. Anda selalu dapat memperoleh manfaat dari implementasi umum jika Anda menggunakan IoC. Anda dapat menentukan antarmuka untuk repositori spesifik Anda dan menyelesaikannya ketika Anda benar-benar memerlukan beberapa tindakan tertentu.


0
2017-07-31 19:25