Veri aktarım nesneleri (DTO'lar) neden bir anti-modeldir?


132

Son zamanlarda insanların veri aktarım nesnelerinin (DTO'lar) bir anti-model olduğunu söylediklerine kulak misafiri oldum .

Neden? Alternatifler neler?


11
Belki de iş nesneleri kendi verilerini taşıyabildikleri için çok teşekkür ederim!
Zoidberg

13
"Anti-pattern", "15 dakikası uzun zaman önce dolan" cümle için adayım olabilir. Şimdiye kadar "Düşüncemi haklı çıkarmak umurumda değil" ile eş anlamlıdır, "Bu çok iyi biliniyor ..." gibi
Craig Stuntz

6
Zoidberg, tel üzerinden yöntemlerle nesneler göndermek bize CORBA, DCOM ve hafızamı silmeye çalıştığım diğer deneyimleri verdi. Sorun şu ki, er ya da geç insanlar bu yöntemleri çağırmak istiyor .
Craig Stuntz

10
DTOs maalesef J2EE açılımı KURU ilkesini, somutlaştırmak do tekrarı kendin.
joeforker

Bunu okumak isteyebilirsiniz: Veri Aktarım Nesnesi
Utançtır

Yanıtlar:


139

Bazı projelerde tüm veriler iki kez bulunur . Biri etki alanı nesneleri olarak ve bir kez de veri aktarım nesneleri olarak.

Bu çoğaltmanın çok büyük bir maliyeti var , bu yüzden mimarinin buna değer olması için bu ayrımdan büyük bir fayda sağlaması gerekiyor.


5
Lütfen "yüksek maliyeti" ayrıntılı olarak açıklayın. Ayrıca, DTO sınıflarını oluşturmak için kod üretme tekniklerini kullanarak maliyetin neden ortadan kaldırılamayacağını söyleyin.
John Saunders

70
+1. İki defa? Sadece şanslıysanız :-) DTO olarak etki alanı varlıklarını çoğaltan projeler, onları tamamlamak için neredeyse aynı ama çok ince bir şekilde farklı UI fasulyelerine sahip olma eğilimindedir. Bu 3. Ve eğer, tanrı korusun, bir çeşit uzaktan kumanda (web hizmetleri / xml-rpc / her neyse) varsa, kolayca 4 veya 5'e ulaşabilirsiniz.
ChssPly76

17
Şu anda enterpricy 14 katmanlı bir lazanya mimarisi ile çalışıyorum (KIDDING DEĞİL). Sizi temin ederim ki, esas olarak veri aktarıcı için olan 11 ya da öylesine katman ücretsiz değildir.
KarlP

10
Ayrıca, aptal tasarımlarla çalışırken kod oluşturucuları kesinlikle sevsem de, bunlar a) başlangıçta yanlış yaptığınız kesin bir şey. b) ücretsiz gelmiyorlar.
KarlP

7
Üzgünüm ama bu sadece yanlış ve yanlış cevap yüksek oylanarak kabul edildi. Öncelikle, anında DTO'lar oluşturmak için yansımayı kullanabilirsiniz. İkinci olarak, örneğin bir CASE sisteminde veya oAW'da bir "kök tanımı" kullanabilir ve BO ve DTO (lar) ı oluşturabilirsiniz. Üçüncüsü, DTO'lar oluşturmak için bir XSD ve JAXB kullanabilir ve DTO'yu bir BO için temel olarak kullanabilirsiniz veya her ikisini de XSD'den oluşturabilirsiniz ... bir müşteri programına
bağlanın

128

DTO'lar bir anti-model değildir. Kablodan bazı verileri gönderirken (örneğin, bir Ajax çağrısındaki bir web sayfasına), yalnızca hedefin kullanacağı verileri göndererek bant genişliğini koruduğunuzdan emin olmak istersiniz. Ayrıca, sunum katmanının verileri yerel bir iş nesnesinden biraz farklı bir formatta olması genellikle uygundur.

Bunun Java odaklı bir soru olduğunu biliyorum, ancak .NET dillerinde anonim türler, serileştirme ve LINQ, DTO'ların anında oluşturulmasına olanak tanıyor ve bu da onları kullanmanın kurulumunu ve ek yükünü azaltıyor.


15
@John, Bu yanlış. Onu her zaman yaparım. Serileştirme, anonim türlerde gayet iyi çalışan yansıma kullanır. Nesne olarak serileştiriciye aktarmanız yeterli. Ve bir kez serileştirildikten sonra (örneğin xml veya json'a) elbette bir yöntemden geri döndürebilirsiniz.
Gabe Moothart

8
John, bu doğru değil. Anonim türleri JSON olarak serileştirebilirsiniz. Bir MVC uygulamasında deneyin: return Json (yeni {Foo = "Merhaba!}); Sana söz veriyorum gayet iyi çalışıyor. Anonim olmayan türlerden daha iyi, çünkü anonim türlerin genellikle nesne grafiklerinde döngüleri yok JSON serileştiricisini bozan
Craig Stuntz

1
Json serileştirme bu anlamda bir DTO değildir ve bu nedenle geçerli değildir. O zaman elbette, yukarıdaki argümanlar da geçerli, bir noktada, buna değer olmayı bırakıyorlar.
Jim Barrows

1
Gabe haklı, DTO tek başına bir anti-model değildir (ancak yanlış kullanılırsa olabilir!), Veri çoğaltması olmadığında. Örneğin, BO, farklı kaynaklardan gelen verileri bir DTO'da toplayabilir.
astro

3
+1. Ve bant genişliği korumasının yanı sıra DTO'ları istemeniz için birçok başka neden var. Kablo boyunca her alanı göndermenize (şirket politikası veya yasaya göre) İZİN VERİLİYOR MUSUNUZ? Ayrıca, şirketimizde DAO'muz çok karmaşık çünkü tüm bu optimizasyonları yapması gerekiyor - hizmet katmanında çalışarak, bir DTO kullandıklarından gerçekten memnunum ve Object X'in sahip olduğu ilişki konusunda bizi endişelendirmiyorlar başka bir n'den n'ye tabloya.
user64141

25

EJB 3.0'daki bir AntiPattern DTO diyor ki:

EJB 3.0'dan önceki EJB spesifikasyonlarındaki Varlık Fasulyelerinin ağır yapısı, Veri Aktarım Nesneleri (DTO) gibi tasarım modellerinin kullanılmasıyla sonuçlandı. DTO'lar, verileri katmanlar arasında göndermek için kullanılan hafif nesneler (ilk etapta varlığın kendilerini çekmesi gerekirdi) haline geldi ... şimdi EJB 3.0 özelliği, Varlık çekirdek modelini Düz eski Java nesnesi (POJO) ile aynı yapıyor. Bu yeni POJO modeliyle, artık her varlık veya bir dizi varlık için bir DTO oluşturmanız gerekmeyecek ... EJB 3.0 varlıklarını katman boyunca göndermek istiyorsanız, onları yalnızca java.io'yu uygulayın.


6
Bellekte, aynı JVM'deki yöntemler arasında nesneler aktarırken doğrudur. Aslında kablo üzerinden serileştirirken ve ne kadar derinlikte serileştireceğinizi ve / veya tembel yüklemeyi koruyacağınızı kontrol etmek istediğinizde doğru değildir.
wrschneider

Evet ve aynı JVM'de bile, JEE / Spring işlem yönetimini kullanıyorsanız aynı tead'de kalmaya gerçekten özen göstermelisiniz.
Marc

20

DTO'ların kendiliğinden bir anti-model olduğunu düşünmüyorum, ancak DTO'ların kullanımıyla ilişkili anti-modeller var. Bill Dudney, DTO patlamasından örnek olarak:

http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf

Ayrıca burada bahsedilen bir dizi DTO suistimali vardır:

http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/

Katmanlar arasında veri aktarımı için bir araç olarak üç katmanlı sistem (tipik olarak teknoloji olarak EJB'yi kullanır) nedeniyle ortaya çıktılar. Spring gibi çerçevelere dayalı modern zamanların çoğu Java sistemi, POJO'ları tek bir katmanda etki alanı nesneleri olarak (genellikle JPA vb. İle açıklanır) kullanarak alternatif basitleştirilmiş bir görünüm alır ... Burada DTO'ların kullanılması gereksizdir.


3
Doğru bağlamda kullanıldıklarında , DTO'ların bir anti-model değil, iyi bir model olduğu konusunda tamamen haklısınız . İkinci bağlantınız şu anda ölü görünüyor, ancak gördüğüm en büyük kötüye kullanım, her etki alanı nesnesinin, hiçbir değer katmayan ve hiç DTO olmayan veritabanı etkileşimi için karşılık gelen bir "DTO" ya sahip olduğu yerdir!
David

19

OO sadeliği, DTO'nun anti-model olduğunu söyler çünkü nesneler gerçek etki alanı nesneleri yerine veri tablosu temsilleri haline gelir.


9

Bazıları, olası suistimalleri nedeniyle DTO'ları bir anti-model olarak görüyor. Genellikle gerekmemesi / gerekmemesi gerektiğinde kullanılırlar.

Bu makale bazı kötüye kullanımları belirsiz bir şekilde açıklamaktadır.


1
Makale DTO'ları kötüye kullanılabilecek bir model olarak çok daha doğru bir şekilde tanımlamaktadır.
Craig Stuntz

Bu yalnızca bağlantı içeren bir cevap anlamına gelir, gerçekten en azından makaleden bir alıntıya ihtiyaç duyar. Bunun Yanıt Değil olarak işaretlenmemesini nasıl başardığını bilmiyorum.
Nathan Hughes


7

Dağıtılmış bir sistem kuruyorsanız, DTO'lar kesinlikle bir anti model değildir. Herkes bu anlamda gelişmeyecektir, ancak (örneğin) bir Open Social uygulamanız varsa, tümü JavaScript ile çalışıyor.

API'nize bir sürü veri gönderecektir. Bu daha sonra bir tür nesneye, tipik olarak bir DTO / Request nesnesine dönüştürülür. Bu, daha sonra bir model nesnesine dönüştürülmeden önce girilen verilerin doğru olduğundan emin olmak için doğrulanabilir.

Bana göre, yanlış kullanıldığı için bir anti-model olarak görülüyor. Dağıtılmış bir sistem kurmuyorsanız, büyük olasılıkla bunlara ihtiyacınız yoktur.


4

Bir Veri Aktarım Nesnesinin amacı, farklı kaynaklardan gelen verileri depolamak ve ardından bunları aynı anda bir veritabanına (veya Uzak Cephe ) aktarmaktır .

Bununla birlikte, DTO modeli sadece verileri depolamakla kalmayıp aynı zamanda veri tabanından / cepheye veya veritabanına / cepheye aktardığından , Tek Sorumluluk İlkesini ihlal eder .

Veri nesnelerini iş nesnelerinden ayırma ihtiyacı bir anti-model değildir, çünkü muhtemelen veritabanı katmanını yine de ayırmak gerekir .

DTO'lar yerine, nesnelerin koleksiyonunu ( Agrega ) ve veri transferini ( Depo ) ayıran Agrega ve Depo Modellerini kullanmalısınız .

Bir nesne grubunu aktarmak için , bir dizi Depo ve bir işlem bağlamını tutan İş Birimi modelini kullanabilirsiniz ; işlem içinde toplamdaki her nesneyi ayrı ayrı aktarmak için.


4

Tüm etki alanı nesneleriniz ilişkili nesneleri EAGERly yüklediğinizde DTO bir zorunluluk haline gelir ve bir ANTI-DESEN değil.

DTO'lar yapmazsanız, iş katmanınızdan istemci / web katmanınıza gereksiz nesneler aktarmış olursunuz.

Bu durumda ek yükü sınırlamak için DTO'ları transfer edin.


1

Soru "neden" değil, " ne zaman " olmalıdır " olmalıdır.

Kesin olarak, yalnızca kullanmanın sonucu daha yüksek maliyet olduğunda anti-modeldir çalışma zamanı veya bakım -. Veritabanı varlık sınıflarıyla özdeş yüzlerce DTO'ya sahip projeler üzerinde çalıştım. DTO'ya, varlığa, DTO'dan etki alanı sınıflarına veya varlıklarına dönüştürmeye, tersine dönüştürme gibi dört kez kimlik eklemek için reklam yaptığınız tek bir alanı her eklemek istediğinizde ... Bazı yerleri ve verileri unuttunuz tutarsız.

Bu var gerçekten etki sınıflarının farklı temsilini gerektiğinde anti-desen değil - daha düz, daha zengin, daha dar, ...

Şahsen ben alan sınıfıyla başlıyorum ve doğru yerlerde uygun şekilde kontrol ederek bunu başkasına veriyorum. Eşleme yapmak için, veritabanına, JSON veya XML gibi serileştirme formatlarına bazı "yardımcı" sınıflar ekleyebilir ve / veya ekleyebilirim ... Gerekirse bir sınıfı ikiye bölebilirim.

Bu sizin bakış açınızla ilgili - Bir etki alanı nesnesine, birbirinden oluşturulan birden çok nesne yerine, çeşitli roller oynayan tek bir nesne olarak bakmayı tercih ederim. Bir nesnenin sahip olduğu tek rol veri taşımaksa, o zaman DTO'dur.


1

Bence insanlar, tüm uzak nesneleri DTO'lar olarak uygularsanız bunun bir anti-model olabileceğini kastediyor. Bir DTO yalnızca bir nitelikler kümesidir ve büyük nesneleriniz varsa, ihtiyacınız olmasa veya kullanmasanız bile her zaman tüm özellikleri aktarırsınız. İkinci durumda, bir Proxy kalıbı kullanmayı tercih edin.

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.