डेटा ट्रांसफर ऑब्जेक्ट्स (DTO) एक एंटी-पैटर्न क्यों हैं?


132

मैंने हाल ही में लोगों को यह कहते हुए सुना है कि डेटा ट्रांसफर ऑब्जेक्ट्स (DTO) एक एंटी-पैटर्न हैं

क्यों? विकल्प क्या हैं?


11
शायद इसलिए कि व्यावसायिक वस्तुएं स्वयं अपने डेटा के परिवहन में सक्षम हैं, आपका बहुत-बहुत धन्यवाद!
Zoidberg

13
"एंटी-पैटर्न" अच्छी तरह से मेरा नामिती हो सकता है "वाक्यांश के लिए जिसका 15 मिनट पहले एक लंबा समय था।" यह अब तक "मेरी सोच को सही ठहराने के लिए परेशान नहीं है" का पर्याय है, जैसे "यह अच्छी तरह से ज्ञात है कि ..."
क्रेग स्टंट्ट

6
Zoidberg, वायर पर तरीकों के साथ ऑब्जेक्ट्स भेजकर हमें CORBA, DCOM और अन्य अनुभव दिए गए हैं जिनकी कोशिश से मैं अपनी मेमोरी को मिटा देता हूं। परेशानी यह है कि जल्दी या बाद में लोग उन तरीकों को कॉल करना चाहते हैं ।
क्रेग स्टंट्ट

10
DTOs सूखी सिद्धांत है, जो J2EE में दुर्भाग्य के लिए खड़ा है प्रतीक करते अपने आप को दोहराने।
जोफॉर्कर

आप इसे पढ़ना चाह सकते हैं: डेटा ट्रांसफर ऑब्जेक्ट इज़ अ शेम
yegor256

जवाबों:


139

कुछ परियोजनाओं में दो बार सभी डेटा होते हैं । एक बार डोमेन ऑब्जेक्ट के रूप में, और एक बार डेटा ट्रांसफर ऑब्जेक्ट के रूप में।

इस दोहराव की एक बड़ी लागत है , इसलिए वास्तुकला को इस मूल्य से अलग होने के लिए एक बड़ा लाभ प्राप्त करने की आवश्यकता है।


5
कृपया "बड़ी लागत" पर विस्तार से बताएं। इसके अलावा, डीटीओ कक्षाओं को जेनरेट करने के लिए कोड जनरेशन तकनीकों का उपयोग करके लागत को समाप्त क्यों नहीं किया जा सकता है।
जॉन सॉन्डर्स 20

70
+1। दो बार? केवल अगर आप भाग्यशाली हैं :-) डीटीओ के रूप में डोमेन संस्थाओं की नकल करने वाली परियोजनाएं भी उन्हें पूरक करने के लिए लगभग-ही-लेकिन-ओह-तो-सूक्ष्म रूप से अलग-अलग यूआई बीन्स हैं। वह 3. और अगर, भगवान न करे, तो किसी तरह की रीमोटिंग (वेब ​​सेवाओं / xml-rpc / जो कुछ भी हो) चल रही है, आप आसानी से 4 या 5 पर पहुंच सकते हैं
ChssPly76

17
मैं वर्तमान में एक एंटरप्रीसी 14 लेयर लसग्ना आर्किटेक्चर (नॉट किडिंग) के साथ काम कर रहा हूं। मैं आपको आश्वस्त कर सकता हूं कि 11-या तो परतें जो मुख्य रूप से डेटा-ट्रांसफर के लिए हैं, मुफ्त में नहीं आती हैं।
कार्ल सिप 18'09

10
इसके अलावा, जब मैं बेवकूफ डिजाइन के साथ काम करते समय बिल्कुल कोड जनरेटर करता हूं, तो वे क) एक निश्चित चीज हैं, जिसे आप शुरू करने के लिए गलत कर रहे हैं। b) वे मुफ्त में नहीं आते हैं।
कार्ल सिप

7
क्षमा करें, लेकिन यह सिर्फ गलत है और गलत उत्तर को उच्च वोट दिया गया और स्वीकार किया गया। सबसे पहले आप मक्खी पर डीटीओ उत्पन्न करने के लिए प्रतिबिंब का उपयोग कर सकते हैं। दूसरा आप एक "रूट परिभाषा" का उपयोग कर सकते हैं, जैसे कि एक CASE सिस्टम या oAW में और BO और DTO (s) जेनरेट करते हैं। आप में से सभी एक XSD और JAXB का उपयोग डीटीओ को जेनरेट करने के लिए कर सकते हैं और एक BO के लिए आधार के रूप में DTO का उपयोग कर सकते हैं, या आप XSD से दोनों को जेनरेट कर सकते हैं ... वैसे भी, अगर किसी को भी एक EJB को डीबी ओवर से नए सिरे से लाने की हिम्मत होगी। एक ग्राहक कार्यक्रम के लिए तार ... वातावरण में मैं काम करता हूं, उसका सिर जल्द ही एक चांदी की प्लेट पर होगा ...
एन्जिल ओ'सेफेरे

128

DTO एक प्रतिमान नहीं हैं। जब आप तार के पार कुछ डेटा भेज रहे हों (जैसे कि अजाक्स कॉल में एक वेब पेज पर), तो आप यह सुनिश्चित करना चाहते हैं कि आप बैंडविड्थ का संरक्षण केवल उस डेटा को भेजकर करें जिसका गंतव्य उपयोग करेगा। इसके अलावा, अक्सर प्रेजेंटेशन लेयर के लिए डेटा को देशी व्यावसायिक ऑब्जेक्ट की तुलना में थोड़ा अलग प्रारूप में रखना सुविधाजनक होता है।

मुझे पता है कि यह एक जावा-उन्मुख प्रश्न है, लेकिन .NET भाषाओं में अनाम प्रकार, क्रमांकन और LINQ डीटीओ को ऑन-द-फ्लाई का निर्माण करने की अनुमति देता है, जो सेटअप और ओवरहेड का उपयोग कम करता है।


15
@ जॉन, यह गलत है। मुझे हर व़क्त यह करना है। सीरियलाइज़ेशन प्रतिबिंब का उपयोग करता है, जो गुमनाम प्रकारों पर ठीक काम करता है। बस इसे एक वस्तु के रूप में धारावाहिक के लिए पास करें। और एक बार यह सिलसिलेवार (xml या json के लिए, उदाहरण के लिए) निश्चित रूप से आप इसे एक विधि से वापस कर सकते हैं।
गाबे मुथारत

8
उम, जॉन, यह सच नहीं है। अनाम प्रकारों को आप JSON में ठीक कर सकते हैं। इसे MVC ऐप में आज़माएं: Json (नया {Foo = "Hi there!}) लौटें; मैं वादा करता हूं कि आप ठीक काम करते हैं। बेहतर, शायद, गैर-अनाम प्रकारों की तुलना में, क्योंकि गुमनाम प्रकारों में आम तौर पर उनके ऑब्जेक्ट ग्राफ़ में कोई चक्र नहीं होता है। , जो JSON सीरियलाइज़र को
तोड़ते हैं

1
Json क्रमांकन इस अर्थ में एक DTO नहीं है, और इसलिए लागू नहीं होता है। फिर, मेरे तर्क ऊपर भी लागू होते हैं, किसी बिंदु पर, वे बस इसके लायक होना बंद कर देते हैं।
जिम बैरो

1
गैब सही है, डीटीओ एक प्रति-पैटर्न विरोधी नहीं है (लेकिन गलत तरीके से उपयोग किया जा सकता है!) जब कोई डेटा दोहराव नहीं है। उदाहरण के लिए, BO विभिन्न स्रोतों से डेटा को DTO में संयोजित कर सकता है।
एस्ट्रो

3
+1। और बैंडविड्थ संरक्षण के अलावा अन्य बहुत सारे कारण हैं जो आप डीटीओ चाहते हैं। क्या आप तार के पार हर क्षेत्र भेजने के लिए (कंपनी की नीति या कानून द्वारा) भी आवंटित हैं? इसके अलावा, हमारी कंपनी में हमारा DAO बहुत जटिल है, क्योंकि इसे इन सभी अनुकूलन करने की आवश्यकता है - सेवा-परत में काम करना, मुझे वास्तव में खुशी है कि वे एक DTO का उपयोग करते हैं और हमें उस रिश्ते के बारे में चिंता नहीं करते हैं जो ऑब्जेक्ट एक्स है। कुछ अन्य एन-टू-एन टेबल पर।
user64141

25

EJB 3.0 में DTO एक एंटीपैटर्न कहता है:

EJB 3.0 से पहले EJB विनिर्देशों में इकाई बीन्स की भारी वजन प्रकृति, डेटा ट्रांसफर ऑब्जेक्ट्स (DTO) जैसे डिज़ाइन पैटर्न का उपयोग करती है। डीटीओ हल्के ऑब्जेक्ट बन गए (जो पहले से ही इकाई सेम होना चाहिए था), जिसका उपयोग टियर में डेटा भेजने के लिए किया जाता है ... अब ईजेबी 3.0 कल्पना एंटीन बीन मॉडल को प्लेन पुराने जावा ऑब्जेक्ट (पीओजेओ) के समान बनाती है। इस नए POJO मॉडल के साथ, आपको अब प्रत्येक इकाई के लिए या संस्थाओं के एक समूह के लिए एक DTO बनाने की आवश्यकता नहीं होगी ... यदि आप EJB को भेजना चाहते हैं तो 3.0 इकाइयाँ टीयर भर में बना सकती हैं और उन्हें लागू करें java.io.Serialiazable


6
जब आप मेमोरी में समान JVM के तरीकों के बीच ऑब्जेक्ट ट्रांसफर कर रहे हों, तब सही। सच नहीं है जब आप वास्तव में तार पर धारावाहिक कर रहे हैं और नियंत्रण करना चाहते हैं कि धारावाहिक कितना गहरा है, और / या आलसी लोडिंग को संरक्षित करें।
19

हां, और यहां तक ​​कि एक ही जेवीएम में, आपको वास्तव में उसी ध्यान में रहने का ध्यान रखना चाहिए यदि आप जेईई / स्प्रिंग लेनदेन प्रबंधन का उपयोग करते हैं।
मार्क

20

मुझे नहीं लगता कि डीटीओ प्रति एसई के प्रति-प्रतिरूप हैं, लेकिन डीटीओ के उपयोग से जुड़े एंटीपैटर्न हैं। एक उदाहरण के रूप में बिल ड्यूडी डीटीओ विस्फोट को संदर्भित करता है:

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

यहाँ उल्लिखित डीटीओ की कई गालियाँ भी हैं:

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

वे तीन स्तरीय प्रणालियों (आमतौर पर तकनीक के रूप में ईजेबी का उपयोग करके) के कारण उत्पन्न हुए, जो कि स्तरों के बीच डेटा को पारित करने के साधन के रूप में हैं। अधिकांश आधुनिक दिन जावा सिस्टम फ्रेमवर्क पर आधारित होते हैं, जैसे कि स्प्रिंग में POJOs का उपयोग डोमेन ऑब्जेक्ट्स (अक्सर JPA आदि के साथ एनोटेट ...) के रूप में एक वैकल्पिक सरलीकृत दृश्य के रूप में किया जाता है ... यहां DTO का उपयोग अनावश्यक है।


3
आप पूरी तरह से सही हैं कि डीटीओ एक अच्छा पैटर्न है , न कि एक विरोधी पैटर्न, जब उनके उचित संदर्भ में उपयोग किया जाता है। आपका दूसरा लिंक अभी मृत प्रतीत होता है, लेकिन मैंने जो सबसे बड़ा दुरुपयोग देखा है वह यह है कि हर डोमेन ऑब्जेक्ट में डेटाबेस इंटरेक्शन के लिए एक समान "डीटीओ" था, जिसका कोई मूल्य नहीं था और डीटीओ बिल्कुल भी नहीं था!
डेविड

19

OO के शुद्धतावादी कहेंगे कि DTO पैटर्न-विरोधी है क्योंकि ऑब्जेक्ट वास्तविक डोमेन ऑब्जेक्ट के बजाय डेटा टेबल प्रतिनिधित्व बन जाते हैं।


9

कुछ डीटीओ को उनके संभावित दुर्व्यवहारों के कारण एक विरोधी पैटर्न मानते हैं। वे अक्सर उपयोग किया जाता है जब वे नहीं होना चाहिए / नहीं होना चाहिए।

यह लेख अस्पष्ट रूप से कुछ अपशब्दों का वर्णन करता है।


1
लेख बहुत अधिक सटीक रूप से डीटीओ को एक पैटर्न के रूप में वर्णित करता है जिसका दुरुपयोग किया जा सकता है।
क्रेग स्टंट्ट

यह केवल एक लिंक-उत्तर के लिए है, यह वास्तव में लेख से कम से कम एक उद्धरण की आवश्यकता है। पता नहीं कैसे यह एक उत्तर के रूप में चिह्नित नहीं किया गया।
नाथन ह्यूजेस


7

यदि आप एक वितरित प्रणाली का निर्माण कर रहे हैं, तो डीटीओ निश्चित रूप से एक विरोधी पैटर्न नहीं हैं। हर कोई उस अर्थ में विकसित नहीं होगा, लेकिन अगर आपके पास (उदाहरण के लिए) ओपन सामाजिक ऐप सभी जावास्क्रिप्ट से चल रहा है।

यह आपके API पर डेटा का लोड पोस्ट करेगा। यह तब वस्तु के किसी रूप में deserialized है, आमतौर पर एक DTO / अनुरोध वस्तु। तब यह सुनिश्चित करने के लिए मान्य किया जा सकता है कि दर्ज किया गया मॉडल मॉडल में परिवर्तित होने से पहले सही है।

मेरी राय में, इसे एक एंटी-पैटर्न के रूप में देखा जाता है क्योंकि यह गलत उपयोग है। यदि आप एक वितरित प्रणाली का निर्माण नहीं कर रहे हैं, तो संभावना है कि आपको उनकी आवश्यकता नहीं है।


4

एक के इरादे डाटा ट्रांसफर वस्तु विभिन्न स्रोतों से डेटा स्टोर और फिर एक डेटाबेस (या में स्थानांतरित करना है रिमोट फसाड एक बार में)।

हालाँकि, डीटीओ पैटर्न सिंगल रिस्पॉन्सिबिलिटी सिद्धांत का उल्लंघन करता है , क्योंकि डीटीओ न केवल डेटा स्टोर करता है, बल्कि इसे डेटाबेस या फ़ेसडे से भी स्थानांतरित करता है।

व्यापारिक वस्तुओं से डेटा ऑब्जेक्ट को अलग करने की आवश्यकता एक एंटीपैटर्न नहीं है, क्योंकि संभवतः डेटाबेस परत को वैसे भी अलग करना आवश्यक है ।

डीटीओ के बजाय आपको एग्रीगेट और रिपोजिटरी पैटर्न का उपयोग करना चाहिए, जो वस्तुओं के संग्रह ( एग्रीगेट ) और डेटा ट्रांसफर ( रिपोजिटरी ) को अलग करता है।

ऑब्जेक्ट के एक समूह को स्थानांतरित करने के लिए आप यूनिट ऑफ़ वर्क पैटर्न का उपयोग कर सकते हैं , जो रिपॉजिटरी का एक सेट और एक लेनदेन संदर्भ रखता है; प्रत्येक वस्तु को लेनदेन के भीतर अलग-अलग स्थान पर स्थानांतरित करने के लिए।


4

जब आप अपने सभी डोमेन ऑब्जेक्ट्स से संबंधित ऑब्जेक्ट्स को EAGERly लोड करते हैं तो DTO एक आवश्यकता बन जाता है और ANTI-PATTERN नहीं।

यदि आप डीटीओ नहीं बनाते हैं, तो आपके पास आपके व्यवसाय की परत से आपके ग्राहक / वेब परत तक अनावश्यक स्थानांतरित वस्तुएं होंगी।

इस मामले के लिए ओवरहेड को सीमित करने के लिए, बल्कि डीटीओ को स्थानांतरित करें।


1

प्रश्न "क्यों" नहीं होना चाहिए, लेकिन " कब " होना चाहिए ।

निश्चित रूप से यह एंटी-पैटर्न है जब केवल इसका उपयोग करने का परिणाम उच्च लागत है - रन-टाइम या रखरखाव। मैंने डेटाबेस इकाई वर्गों के समान सैकड़ों डीटीओ वाली परियोजनाओं पर काम किया। प्रत्येक बार जब आप एक एकल फ़ील्ड जोड़ना चाहते थे, जिसमें आप चार बार आईडी जोड़ते हैं - डीटीओ से, इकाई तक, डीटीओ से डोमेन कक्षाओं या संस्थाओं में रूपांतरण करने के लिए, उलटा रूपांतरण, ... आप कुछ स्थानों और डेटा को भूल गए असंगत।

यह विरोधी पैटर्न नहीं है जब आपको वास्तव में डोमेन वर्गों के विभिन्न प्रतिनिधित्व की आवश्यकता होती है - अधिक सपाट, अधिक अमीर, अधिक संकीर्ण, ...

व्यक्तिगत रूप से मैं डोमेन क्लास से शुरू करता हूं और इसे पास करता हूं, सही स्थानों पर उचित जांच के साथ। मैं JSON या XML जैसे क्रमांकन प्रारूपों में डेटाबेस के लिए मैपिंग बनाने के लिए कुछ "हेल्पर" वर्गों को एनोटेट और / या जोड़ सकता हूं ... यदि मुझे आवश्यकता महसूस होती है तो मैं हमेशा कक्षा को दो में विभाजित कर सकता हूं।

यह आपके दृष्टिकोण के बारे में है - मैं एक डोमेन ऑब्जेक्ट को एक ही ऑब्जेक्ट के रूप में देखना पसंद करता हूं, जो एक-दूसरे से निर्मित कई ऑब्जेक्ट्स के बजाय विभिन्न भूमिका निभा रहा है। यदि किसी ऑब्जेक्ट की एकमात्र भूमिका डेटा ट्रांसपोर्ट कर रही है, तो यह डीटीओ है।


1

मुझे लगता है कि लोगों का मतलब है कि अगर आप सभी दूरस्थ वस्तुओं को डीटीओ के रूप में लागू करते हैं तो यह एक विरोधी पैटर्न हो सकता है। एक डीटीओ केवल विशेषताओं का एक सेट है और यदि आपके पास बड़ी वस्तुएं हैं, तो आपको हमेशा सभी विशेषताओं को स्थानांतरित करना होगा, भले ही आपको उनकी आवश्यकता न हो या उनका उपयोग न करें। बाद के मामले में एक प्रॉक्सी पैटर्न का उपयोग करना पसंद करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.