Uzorci dizajna koje često izbjegavam: Uzorak spremišta

Obrasci dizajna pružaju dokazana rješenja za probleme iz stvarnog svijeta s kojima se suočavaju u dizajnu softvera. Uzorak Repozitorija koristi se za razdvajanje poslovne logike i slojeva pristupa podacima u vašoj aplikaciji.

Sloj pristupa podacima obično sadrži kôd specifičan za pohranu i metode rada s podacima do i od pohrane podataka. Sloj pristupa podacima koji repozitorij apstrahira može biti ORM (tj. Entity Framework ili NHibernate), XML datoteka, web usluga itd. To može biti čak i zbirka SQL izraza.

Korištenjem uzorka dizajna Repozitorija, sloj poslovne logike vaše aplikacije ne mora imati nikakvo znanje o tome kako se trajnost podataka događa ispod. U osnovi, spremište posreduje između domene i slojeva mapiranja podataka vaše aplikacije. Trebao bi vam pružiti inkapsulaciju načina na koji se podaci stvarno zadržavaju u sloju za pohranu podataka.

Uzorak Spremišta može biti koristan ako imate mnogo entiteta i imate mnogo složenih upita za rad s tim entitetima. Dodatni sloj apstrakcije u ovom vam slučaju može pomoći u uklanjanju dupliciranja logike upita.

Generičko spremište

Generičko spremište je vrsta koja se sastoji od skupa generičkih metoda za izvođenje CRUD operacija. Međutim, to je samo još jedan anti obrazac i često se koristi s Entity Frameworkom za apstrahiranje poziva na sloj pristupa podacima. Po mom mišljenju, korištenje generičkog spremišta previše je uopćavanje. Loša je ideja apstrahirati pozive na Entity Framework pomoću generičkog spremišta.

Dopustite mi da to objasnim na primjeru.

Sljedeći popis kodova ilustrira generičko spremište - sadrži generičke metode za izvođenje osnovnih CRUD operacija.

public interface IRepository

   {

       IEnumerable GetAll();

       T GetByID(int id);

       void Add(T item);

       void Update(T item);

       void Delete(T item);

   }

Da biste stvorili određeno spremište, tada biste trebali implementirati generičko sučelje kao što je prikazano u donjem popisu kodova.

public class AuthorRepository : IRepository

   {

       //Implemented methods of the IRepository interface

   }

Kao što vidite, da biste stvorili bilo koju određenu klasu spremišta, trebali biste implementirati svaku od metoda sučelja generičkog spremišta. Glavni nedostatak ovog pristupa je taj što biste morali stvoriti novo spremište za svaki entitet.

Evo još jednog nedostatka ovog pristupa: Osnovna namjera uzorka spremišta je razdvojiti sloj domene od načina na koji podaci zapravo postoje u sloju pristupa podacima. Evo ažurirane verzije klase spremišta koju smo upravo stvorili.

public class AuthorRepository : IRepository

   {

       private AuthorContext dbContext;

       //Methods of the IRepository interface

   }

Kao što možete vidjeti u ranije navedenom popisu kodova, AuthorRepository treba instancu AuthorContext za obavljanje CRUD operacija kojima je namijenjen. Pa, gdje je onda razdvajanje? U idealnom slučaju, sloj domene ne bi trebao imati nikakvo znanje o logici postojanosti.

Dodatni sloj apstrakcije

Model domene i model trajnosti u aplikaciji imaju izrazito različite odgovornosti. Dok se prvi modeli ponašaju, tj. Modeliraju stvarne probleme i rješenja tih problema, drugi se koristi za modeliranje kako se podaci aplikacije zapravo pohranjuju u spremište podataka.

Namjera uzorka spremišta trebala bi biti apstrahiranje logike postojanosti i skrivanje internih implementacija načina na koji se podaci održavaju. Operacije spremišta trebaju biti dovoljno izražajne i ne smiju biti generičke. Ne možete imati spremište koje je generičko i koje može sadržavati operacije koje se mogu uklopiti u bilo koji scenarij. To postaje nepotrebna apstrakcija i stoga generički obrazac spremišta čini anti-uzorkom. Sve objekte svoje domene možete modelirati na isti način. Generičko spremište ne definira smislen ugovor i opet bi vam bilo potrebno određeno spremište koje proširuje vaše generičko spremište i pruža određeni skup operacija koje su značajne za taj određeni entitet.

Sad kad već imate nekoliko zrelih tehnologija trajanja podataka (NHibernate, Entity Framework, itd.), Zašto vam je uopće potreban ovaj dodatni sloj apstrakcije? Većina zrelih ORM tehnologija koje su danas dostupne imaju iste mogućnosti. U pokušaju korištenja spremišta, vi samo dodate dodatni sloj apstrakcije bez ikakvog razloga. Kao primjer, možda će vam trebati metode poput sljedeće za vaš AuthorRepository.

FindAuthorById()

FindAuthorByCountry()

To se pogoršava jer imate sve više metoda i složenih pretraživanja - na kraju biste dobili spremište koje bi usko preslikavalo postojani sloj pohrane koji se koristi ispod.