DAO ve Havuz kalıpları arasındaki fark nedir?


Yanıtlar:


472

DAOveri kalıcılığının bir soyutlamasıdır .
Repositorybir nesne koleksiyonunun soyutlamasıdır .

DAOveritabanına daha yakın, genellikle tablo merkezli olarak değerlendirilir.
Repositoryyalnızca Toplu Köklerde işlem yapan Alan Adına daha yakın kabul edilir.

RepositoryDAO's kullanılarak uygulanabilir , ancak tam tersini yapmazsınız.

Ayrıca, a Repositorygenellikle daha dar bir arayüzdür. Bu bir ile, sadece nesneleri topluluğudur olmalıdır Get(id), Find(ISpecification), Add(Entity).

Gibi bir yöntem Updatebir uygun olduğunu DAO, ancak bir değil Repository- bir kullanırken Repository, kuruluşlara değişiklikler genellikle ayrı UnitOfWork tarafından izlenir.

RepositoryGerçekten daha çok olan a olarak adlandırılan uygulamaları görmek yaygın görünmektedir DAOve bu nedenle aralarındaki fark hakkında bazı karışıklıklar olduğunu düşünüyorum.


27
DAO sınıfınızın IRepositoryarayüzünüzü tam anlamıyla uygulamasını istemezsiniz . Deponuzun DAO'ları uygulamasında kullanmasını istersiniz. Unutmayın, bir DAO tablo başına bir nesne olacaktır, ancak bir Havuz neredeyse her zaman tek bir Varlık oluşturmak için birden fazla DAO kullanmalıdır. Durum böyle değilse, Deponuz ve Varlığınızın yalnızca tek bir tabloya erişmesi gerektiğini düşünüyorsanız, büyük olasılıkla bir anemik etki alanı oluşturuyorsunuzdur.
quentin-starin

29
Ben .NET dünyasında özellikle "Depo" terimi aslında bir DAO ne olduğunu belirtmek için kullanılır fark ettim; "DAO" daha çok bir Java terimidir.
Wayne Molina

14
@Doure'larda tablo başına değil, desen yalnızca verilerinize erişimi soyutlamaktadır - bunu istediğiniz gibi uygulayabilirsiniz (tablo veya grup veya model başına). Önerilen yol, DAO'larınızı her zaman etki alanı modelinize göre biçimlendirmektir, çünkü kullanımı daha kolay / net hale getirir ve nasıl devam ettiğiniz konusunda size biraz daha esneklik sağlar (örneğin, ihtiyacınız olacağını hayal edin) verilerinizi XML dosyalarında depolayan veya Veritabanından ziyade bir mesaj kuyruğundan alan bir DAO ...).
Stef

21
@Stef katılmıyorum. Bir DAO verileri tanımına göre döndürür (bir veri erişim nesnesi). Bir havuz, tanımı gereği, etki alanı nesnelerini döndürür. Deponun DAO'ları kullanmasını ve bunun tersini kullanmamasını sağlamalıdır, çünkü OOP'de etki alanı nesnelerini bir veya daha fazla veri nesnesinden oluşturuyoruz, tersi şekilde değil.
Mihai Danila

6
DAO "Okuma ve Yazma" iken bir Havuz neden "Salt Okunur" kavramıdır?
Dennis

121

Tamam, yorumlara ne koyduğumu daha iyi açıklayabileceğimi düşünüyorum :). Yani, DAO, Depo'dan daha esnek bir model olsa da, temel olarak, her ikisini de aynı şekilde görebilirsiniz. Her ikisini de kullanmak isterseniz DAO'larınızdaki Depoyu kullanırsınız. Her birini aşağıda açıklayacağım:

DEPOSU:

Belirli bir nesne türünün deposu - belirli bir nesne türünü aramanıza ve saklamanıza olanak tanır. Genellikle SADECE bir tür nesneyi işler. Örneğin AppleRepository, yapmanıza izin verir AppleRepository.findAll(criteria)veya AppleRepository.save(juicyApple). Deponun Etki Alanı Modeli terimlerini kullandığını unutmayın (DB terimleri değil - verinin her yerde nasıl devam ettiği ile ilgili hiçbir şey yoktur).

Bir veri havuzu büyük olasılıkla tüm verileri aynı tabloda depolayacaktır, ancak kalıp bunu gerektirmez. Yine de yalnızca bir tür veri işleyebilmesi gerçeği, mantıksal olarak bir ana tabloya bağlanır (DB kalıcılığı için kullanılıyorsa).

DAO - veri erişim nesnesi (diğer bir deyişle - verilere erişmek için kullanılan nesne)

DAO, verileri sizin için bulan bir sınıftır (çoğunlukla bir bulucudur, ancak genellikle verileri depolamak için de kullanılır). Kalıp, aynı türdeki verileri depolamanızı kısıtlamaz, böylece ilgili nesneleri bulan / depolayan bir DAO'ya kolayca sahip olabilirsiniz.

Kolayca gibi yöntemleri ortaya Userdao sahip olabilir

Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)

Bunların tümü Kullanıcı (ve güvenlik) ile ilgilidir ve aynı DAO altında belirtilebilir. Depo için durum böyle değil.

En sonunda

Her iki örüntünün gerçekten aynı anlama geldiğini (verileri sakladıklarını ve buna erişimi soyutladıklarını ve her ikisinin de etki alanı modeline daha yakın ifade edildiğini ve neredeyse hiç DB referansı içermediğini) unutmayın, ancak kullanım şekilleri biraz farklı olabilir, DAO biraz daha esnek / genel olurken, Depo yalnızca bir tür için biraz daha spesifik ve kısıtlayıcıdır.


Bunu doğru yaparsam CarDescription, örneğin language_idyabancı anahtar gibi bir şeyim var - o zaman böyle bir şey yapmam gerektiğini almak için: CarRepository.getAll(new Criteria(carOwner.id, language.id));bu bana belirli bir dilde bir dilin tüm arabalarını verecek - bunu yapmanın doğru yolu ?
görünen

@StefanFalk, Spring Data'ya bir göz atın, bundan daha güzel aramalar yapmanıza izin verir. örneğin, bu şekilde yazılabilir CarRepository.findByLanguageId(language.id)ve kodu yazmanız bile gerekmez, sadece bu adla bir yöntemle arayüzü tanımlarsınız ve Spring Data sizin için varsayılan sınıf uygulamasını oluşturmaya özen gösterir. Oldukça temiz şeyler;)
Stef

2
Spring Data'nın güzelliği, aslında sorguları yazmak zorunda olmamanız, sadece bir arayüz oluşturmanızdır (örneğinizde, yönteme sahip olan TodoRepository gibi findById). Ve pratikte bitti. Daha sonra Spring Data'nın yaptığı şey, oluşturduğunuz tüm bu arayüzleri Depo arayüzünü genişleten ve sınıfları sizin için yaratan şeydir. Bu sınıfları asla göremezsiniz ve yeni örnekler oluşturamazsınız, ancak yalnızca arayüzü otomatik olarak bağlayabileceğiniz ve Spring'in bu depo nesnesini bulmasına izin verebileceğiniz için gerekmez.
Stef

1
Son olarak, Bahar Verilerini kullanmak zorunda değilsiniz, sorgu yöntemlerini kendiniz yazmanın eski yoluna gidebilirsiniz (Ölçüt API'sini kullanarak), ancak hayatınızı biraz daha karmaşık hale getireceksiniz ... bunun gibi daha fazla esnekliğe sahip olacaksınız, ancak bu, sorgularınızla gerçekten delirmek istiyorsanız, Spring Data size bunu yapmanın iki yolunu sunuyor: @Query ek açıklaması veya işe yaramazsa, kendi uygulamanızı sıfırdan yazdığınız gibi size aynı gücü veren bir uzantı olan özel depolar oluşturun.
Stef

2
"Birleştirilmiş kök", genellikle veri havuzu modeline bağlı bir terimdir. Bunu bir depo tanımınızla nasıl kullanacağınızı bilmiyorum.
Christian Strempfer

90

DAO ve Havuz kalıbı, Veri Erişim Katmanı'nı (DAL) uygulamanın yoludur. Önce DAL ile başlayalım.

Veritabanına erişen nesne yönelimli uygulamaların, veritabanı erişimini işlemek için bir mantığı olmalıdır. Kodu temiz ve modüler tutmak için veritabanı erişim mantığının ayrı bir modüle ayrılması tavsiye edilir. Katmanlı mimaride bu modül DAL'dir.

Şimdiye kadar, belirli bir uygulamadan bahsetmedik: veritabanı erişim mantığını ayrı bir modüle yerleştiren sadece genel bir prensip.

Şimdi, bu prensibi nasıl uygulayabiliriz? Bunu, özellikle Hibernate gibi çerçevelerle uygulamanın bir yolu DAO modelidir.

DAO modeli, tipik olarak her etki alanı varlığının kendi DAO'suna sahip olduğu DAL oluşturmanın bir yoludur. Örneğin, Userve UserDao, Appointmentve AppointmentDao: vs ile hazırda DAO bir örnek, http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .

O zaman Depo deseni nedir? DAO gibi, Depo deseni de DAL'ye ulaşmanın bir yoludur. Havuz modelindeki ana nokta, istemci / kullanıcı perspektifinden bir koleksiyon olarak görünmesi veya davranmasıdır. Bir koleksiyon gibi davranmakla kastedilen, onun gibi somutlaştırılması gerektiği değildir Collection collection = new SomeCollection(). Bunun yerine, ekleme, kaldırma, içerir, vb. İşlemleri desteklemesi gerektiği anlamına gelir. Bu, Havuz modelinin özüdür.

Uygulamada, örneğin Hazırda Bekletme modunun kullanılması durumunda, DAO ile Havuz kalıbı gerçekleştirilir. Bu bir DAL örneğidir, aynı anda hem DAO kalıbı hem de Depo kalıbı örneği olabilir.

Havuz kalıbı DAO'nun üzerine inşa edilen bir şey olmak zorunda değildir (bazılarının önerebileceği gibi). DAO'lar yukarıda belirtilen işlemleri destekleyen bir arabirim ile tasarlandıysa, Depo modelinin bir örneğidir. Bir düşünün, DAO'lar zaten koleksiyona benzer bir dizi işlem sağlıyorsa, bunun üzerine fazladan bir katmana ne gerek var?


5
"DAO'lar zaten koleksiyona benzer bir dizi işlem sağlıyorsa, bunun üzerine fazladan bir katmana ne gerek var?" Bir evcil hayvan dükkanını modellediğinizi ve farklı hayvanların ve bunların niteliklerinin (ad: "Kedi", tür: "Memeli" vb.) İçeren bir tablonuz olduğunu varsayalım. dükkanda var (adı: "Katniss", cins: "Patiska", vb.). Eğer veritabanında zaten bir tür bir hayvan eklemek isterseniz, DAOs kaplingin kaçınarak, tek yöntemde (Pet diğer PetType ve oluşturmak için bir) iki ayrı DAO çağrıları grubuna bir depo kullanabilirsiniz
Matt

1
Mükemmel açıklama efendim!
Paul-Sebastian Manole

74

Açıkçası, bu teknik bir ayrım değil, anlamsal bir ayrım gibi görünüyor. Veri Erişim Nesnesi ifadesi "veritabanına" hiç değinmez. Ve veritabanına dayalı olacak şekilde tasarlayabilseniz de, çoğu insanın tasarım hatası yapmayı düşüneceğini düşünüyorum.

DAO'nun amacı, veri erişim mekanizmasının uygulama ayrıntılarını gizlemektir. Havuz kalıbı nasıl farklı? Anlayabildiğim kadarıyla değil. Bir Havuz söylemek bir DAO'dan farklıdır çünkü bir nesne koleksiyonu ile uğraşıyorsunuz / geri dönüyorsanız doğru olamaz; DAO'lar ayrıca nesne koleksiyonlarını döndürebilir.

Havuz kalıbı hakkında okuduğum her şey bu ayrıma dayanıyor: kötü DAO tasarımı vs iyi DAO tasarımı (diğer adıyla depo tasarım deseni).


5
evet, tamamen katılıyorum, aslında aynı. DAO daha fazla DB ile ilgili görünüyor, ama değil. Depo ile aynı, verilerin nerede ve nasıl saklandığını gizlemek için kullanılan bir soyutlamadır.
Stef

+1 Bu ifade için. Açıkçası, bu teknik bir ayrım değil, anlamsal bir ayrım gibi görünüyor. Veri Erişim Nesnesi ifadesi "veritabanına" hiç değinmez.
Sudhakar Chavali

1
Depoları ve koleksiyonları karşılaştıran noktası onlar nesnelerin koleksiyonları dönen / ilgileniyor olduğunu değil, ama Depoları davranır onlar sanki olan koleksiyonları kendileri. Örneğin, Java'da, bir koleksiyondaki bir nesneyi değiştirdiğinizde otomatik olarak güncelleştirildiği için (Java koleksiyonları yalnızca nesnelere başvuru depoladığı için) bir Havuzun güncelleme yöntemi olmadığı anlamına gelir.
Christoph Böhme

17

Depo, Etki Alanına Dayalı Tasarımın bir parçası olan daha soyut etki alanına yönelik bir terimdir, etki alanı tasarımınızın ve ortak bir dilin bir parçasıdır, DAO veri erişim teknolojisi için teknik bir soyutlamadır, veri havuzu yalnızca mevcut verilerin ve fabrikaların oluşturulması için yönetilmesiyle ilgilidir veri.

bu bağlantıları kontrol edin:

http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html


6

Temel fark, bir havuzun bir toplamda toplam köklere erişimi, DAO ise varlıklara erişimi yönetmesidir. Bu nedenle, bir havuzun toplam köklerin gerçek kalıcılığını bir DAO'ya devretmesi yaygındır. Ayrıca, toplam kök diğer varlıkların erişimini işlemesi gerektiğinden, bu erişimi diğer DAO'lara devretmesi gerekebilir.


5

DAO, veritabanı / veri dosyaları veya başka bir kalıcılık mekanizması üzerinde soyutlama sağlar, böylece kalıcılık katmanı uygulama ayrıntılarını bilmeden manipüle edilebilir.

Depo sınıflarında ise, "uygulama perspektifinden" bir işlem yapmak için tek bir Depo yönteminde birden çok DAO sınıfı kullanılabilir. Bu nedenle, Etki Alanı katmanında birden çok DAO kullanmak yerine, işlemi gerçekleştirmek için havuzu kullanın. Depo, aşağıdakiler gibi bazı uygulama mantığı içerebilen bir katman : Bellek içi önbellekte veri varsa, önbellekten alın, aksi takdirde ağdan veri alın ve bir dahaki sefere almak için bellek içi önbellekte saklayın.


3

Depo, iyi tasarlanmış DAO'dan başka bir şey değildir.

ORM tablo merkezli ancak DAO değil.

Depoda birkaç DAO kullanmaya gerek yoktur, çünkü DAO'nun kendisi bir aracın nerede ve nasıl ısrar ederse sürsün ORM depoları / varlıkları veya herhangi bir DAL sağlayıcısı ile tam olarak aynı şeyi yapabilir 1 tablo, 2 tablo, n tablo, yarım masa, a web servisi, tablo ve web servisi vb. Hizmetler çeşitli DAO / depolar kullanır.

Kendi DAO'm, diyelim ki Cardao sadece Araba DTO ile ilgileniyor, yani, sadece Araba DTO'yu girişe alın ve sadece araba DTO veya araba DTO koleksiyonlarını iade edin.

Tıpkı Depo gibi, DAO aslında iş mantığı için sebat arayüzlerinin sebat stratejileri veya mirasları tarafından korkutulmamasına izin veren bir IoC'dir. DAO hem kalıcılık stratejisini kapsüllemekte hem de domaine ile ilgili kalıcılık arayüzünü sunmaktadır. Depo, iyi tanımlanmış bir DAO'nun gerçekte ne olduğunu anlamayanlar için başka bir kelimedir.


Her şeyden önce "ORM depoları / varlıkları"? ORM varlıkları demek istiyorsun. ORM deposu diye bir şey yoktur. İkincisi, ORM'ler genellikle sadece varlıklarla ilgilenir, yani. etki alanı modelleri. DAO'lar doğrudan tablolarla ve soyut veri erişimiyle ilgilenir. Varlıkları da iade ediyorlar. Depolar, varlık elde etmek için bir koleksiyon arayüzü sunan en yüksek soyutlamadır. Bir DAO, bir veri havuzu olabilir, yani. gerçek depolama motorunu soyutlamak, ona bir arayüz sunmak ve ayrıca (önbellek) varlıkların bir koleksiyon görünümünü sunmak. DAO, veritabanıyla arabirim oluşturmak ve varlık işlemlerini devretmek için ORM kullanabilir.
Paul-Sebastian Manole

3
@Brokenthorn ile aynı fikirde. Yorumundaki en önemli nokta "Depolar en yüksek soyutlamadır" ve etki alanı kodunuzu temeldeki veritabanı teknolojisinden korumak istediğinizde bu soyutlama bir zorunluluk haline gelir. ORM / Adaptör / DB Sürücüsü kavramları DAO'lara sızma eğilimindedir. Birden fazla veritabanı teknolojisini destekleyen bir uygulamanız varsa veya uygulamanızın bir veritabanına kilitlenmesini istemiyorsanız, doğrudan etki alanı modelinden DAO'ları kullanmak hareketsizdir.
Subhash Bhushan

2

DAO'nun veya Havuz kalıbının aşağıdaki durum için en uygun olup olmadığını bulmaya çalışın: RDBMS, LDAP, OODB, XML depoları ve düz dosyalar.

İlgileniyorsanız aşağıdaki bağlantılara da bakın:

http://www.codeinsanity.com/2008/08/repository-pattern.html

http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/

http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx

http://en.wikipedia.org/wiki/Domain-driven_design

http://msdn.microsoft.com/en-us/magazine/dd419654.aspx


0

çok basit bir cümle: DAO'lar veritabanına daha yakınken, genellikle çok daha tablo merkezli olmak üzere, Depoların koleksiyonları temsil etmesidir.


DAO da koleksiyonları / nesneleri temsil edebilir ...
Yousha Aleayoub

0

Bahar çerçevesinde, depo adı verilen bir ek açıklama vardır ve bu ek açıklamanın açıklamasında, bu tartışma için yararlı olduğunu düşündüğüm depo hakkında yararlı bilgiler vardır.

Açıklamalı bir sınıfın, başlangıçta Etki Alanına Dayalı Tasarım (Evans, 2003) tarafından "bir nesne koleksiyonunu taklit eden depolama, geri alma ve arama davranışını kapsüllemek için bir mekanizma" olarak tanımlanan bir "Havuz" olduğunu belirtir.

"Veri Erişim Nesnesi" gibi geleneksel Java EE kalıpları uygulayan ekipler de bu klişeyi DAO sınıflarına uygulayabilirler, ancak bunu yapmadan önce Veri Erişim Nesnesi ile DDD stili depolar arasındaki ayrımı anlamak için özen gösterilmelidir. Bu açıklama genel amaçlı bir stereotiptir ve bireysel ekipler anlambilimlerini daraltabilir ve uygun şekilde kullanabilirler.

Bu şekilde açıklamalı bir sınıf, bir PersistenceExceptionTranslationPostProcessor ile birlikte kullanıldığında Spring DataAccessException çevirisi için uygundur. Ek açıklamalı sınıf ayrıca takımlama, yönler, vb. Amaçlarıyla genel uygulama mimarisindeki rolü konusunda açıklığa kavuşturulmuştur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.