2009-03-24 19 views
59

मैंने डोमेन ऑब्जेक्ट्स पर डीटीओ मैपिंग से संबंधित बहुत सारे प्रश्न देखे हैं, लेकिन मुझे नहीं लगता कि उन्होंने मेरे प्रश्न का उत्तर दिया है। मैंने अपनी खुद की राय से पहले कई तरीकों का उपयोग किया है लेकिन मैं कुछ और ठोस बनाने की तलाश में हूं।डोमेन ऑब्जेक्ट पर डीटीओ मैपिंग के लिए सर्वोत्तम अभ्यास?

स्थिति:

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

मेरा प्रश्न यह है कि डीटीओ और डोमेन ऑब्जेक्ट को कैसे जोड़ा जाना चाहिए?

मेरी पहली प्रतिक्रिया Fowler, DTO pattern-type solution का उपयोग करना है। मैंने इसे कई बार देखा है और यह मेरे लिए सही लगता है। डोमेन ऑब्जेक्ट में डीटीओ का कोई संदर्भ नहीं है। एक डोमेन ऑब्जेक्ट से एक डीटीओ बनाने के लिए एक बाहरी इकाई (एक "मैपर" या "असेंबलर") कहा जाता है। आम तौर पर डोमेन ऑब्जेक्ट पक्ष पर एक ओआरएम होता है। इसका नकारात्मक पक्ष यह है कि "मैपर" किसी भी वास्तविक स्थिति के लिए बेहद जटिल हो जाता है और यह बहुत नाजुक हो सकता है।

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

क्या अन्य तरीके हैं? उपयोग करने के लायक तरीकों में से एक है? यदि ऐसा है या नहीं, तो क्यों?

अग्रिम में किसी भी अंतर्दृष्टि के लिए धन्यवाद।

+2

ऑटोमैपर दिलचस्प लग रहा है। मैंने पहले कोड को देखा है इससे पहले कि यह बदलेगा। मेरा मुख्य मुद्दा यह है कि यदि मैं किसी भी कारण से मैपिंग कोड के टन के साथ फंस जाऊंगा, तो मैं इसे अपने ऊपर नियंत्रण रखना पसंद करूंगा। –

+2

जब हम डीटीओ _to_ डोमेन ऑब्जेक्ट्स से जाते हैं, तो मैपिंग 100% मैन्युअल है। हल करने के लिए यह एक कठिन समस्या है, क्योंकि हम केवल डेटा कंटेनर के बजाय, हमारे डोमेन ऑब्जेक्ट्स को ऑपरेशन-आधारित रखने की कोशिश करते हैं। _to_ एक डीटीओ जा रहा है, यह हल करने में एक आसान समस्या है। –

+0

मैं इस बात से सहमत हूं कि यह गलत है कि डोमेन ऑब्जेक्ट को डीटीओ ऑब्जेक्ट का कोई ज्ञान नहीं होना चाहिए। हालांकि वे इस मामले में संबंधित हो सकते हैं, उनका उद्देश्य पूरी तरह से अलग है (डीटीओ आमतौर पर उद्देश्य के लिए बनाए जाते हैं) और आप एक अनावश्यक निर्भरता बनायेंगे। – Sinaesthetic

उत्तर

33

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

व्यक्तिगत रूप से, मैं अपने डोमेन इकाइयों से मैपिंग को आजमाकर रखता हूं और जिम्मेदारी देता हूं जिसे मैं "प्रबंधक/सेवा परत" कहता हूं। यह एक परत है जो एप्लिकेशन और सशर्त (ies) के बीच बैठती है, और वर्कफ़्लो समन्वय जैसे व्यवसाय तर्क प्रदान करती है (यदि आप ए को संशोधित करते हैं, तो आपको बी को भी संशोधित करना होगा ताकि सेवा ए सेवा बी के साथ काम करे)।

यदि मेरे पास बहुत से संभावित समापन प्रारूप थे, तो मैं एक प्लग करने योग्य फॉर्मेटर बनाने की सोच सकता हूं जो आगंतुक पैटर्न का उपयोग कर सकता है, उदाहरण के लिए मेरी संस्थाओं को बदलने के लिए, लेकिन मुझे इस जटिलता के लिए अभी तक कोई आवश्यकता नहीं मिली है।

22

आप the one written by Jimmy Bogard जैसे ऑटोमैपर का उपयोग कर सकते हैं जिसमें ऑब्जेक्ट्स के बीच कोई संबंध नहीं है और अनुपालन नामकरण सम्मेलनों पर निर्भर करता है।

+3

ऑटोमैपर दुर्घटनाग्रस्त संपत्तियों -> सुरक्षा छेद का कारण बन सकता है। स्पष्ट रूप से कहना बेहतर होगा कि डीटीओ के रूप में क्या खुलासा किया जाना चाहिए। – deamon

+4

@deamon: वैध चिंता, लेकिन बग (और मानव निरीक्षण की वजह से संभावित सुरक्षा छेद) भी है जो कि सभी gooey मैपिंग कोड लिखने के लिए बनाया जा सकता है। मैं ऑटोमैटिक रोड पर जाउंगा और कस्टम मैपिंग फीचर में निर्मित 5% को संभालेगा। – Merritt

+0

@deamon - क्या आप उन संपत्तियों के लिए सशर्त मैपिंग नहीं कर सकते हैं जिन्हें आपको उजागर नहीं करना चाहिए? सोच रहा है कि ऑटोमैपर उस परिदृश्य को संभालता है? –

0

आप ओटिस, ऑब्जेक्ट-टू-ऑब्जेक्ट मैपर भी आज़मा सकते हैं। अवधारणा NHibernate मैपिंग (विशेषता या एक्सएमएल) के समान हैं।

http://code.google.com/p/otis-lib/wiki/GettingStarted

1

एक अन्य संभावित समाधान: http://glue.codeplex.com

विशेषताएं:

  • द्वि-दिशा मानचित्रण
  • स्वचालित मानचित्रण
  • विभिन्न प्रकार
  • नेस्टेड मानचित्रण और
  • सूचियों और सरणी सपाट बीच
  • मानचित्रण
  • संबंधों
  • परीक्षण का सत्यापन मानचित्रण
  • गुण, फील्ड्स और तरीके
5

हम टी -4 टेम्पलेट का उपयोग मानचित्रण कक्षाएं बनाने के लिए।

प्रो - मानव पठनीय कोड संकलन समय पर उपलब्ध, रनटाइम मैपर से तेज़। कोड पर 100% नियंत्रण (विज्ञापन-हॉक आधार पर कार्यक्षमता बढ़ाने के लिए आंशिक विधियों/टेम्पलेट पैटर्न का उपयोग कर सकते हैं)

कॉन - कुछ गुणों को छोड़कर, डोमेन ऑब्जेक्ट्स के संग्रह इत्यादि, टी 4 सिंटैक्स सीखना।

0

मैं अपने द्वारा बनाए गए टूल का सुझाव दे सकता हूं और कोडप्लेक्स पर होस्ट किया गया ओपन सोर्स है: EntitiesToDTOs

डीटीओ से एंटिटी तक मैपिंग और इसके विपरीत विस्तार विधियों द्वारा कार्यान्वित किया जाता है, ये प्रत्येक छोर के असेंबलर पक्ष को लिखते हैं।

आप की तरह कोड के साथ समाप्त:

Foo entity = new Foo(); 
FooDTO dto = entity.ToDTO(); 
entity = dto.ToEntity(); 

List<Foo> entityList = new List<Foo>(); 
List<FooDTO> dtoList = entityList.ToDTOs(); 
entityList = dtoList.ToEntities(); 
+0

यह वास्तुकला में गलत है क्योंकि आप डीटीओ और डोमेन इकाइयों को एक दूसरे के बारे में जानते हैं। – Raffaeu

+5

@Raffaeu मुझे ऐसा नहीं लगता क्योंकि TODTO/ToDTOs/ToEntity/ToEntities विधियों को एक्सटेंशन विधियों के रूप में परिभाषित किया गया है जो असेंबलर्स का प्रतिनिधित्व करते हैं। एक इकाई को एक डीटीओ में परिवर्तित करने का तर्क और इसके विपरीत, विस्तार विधियों (असेंबलर) में है, वास्तव में इकाई/डीटीओ में नहीं। – kzfabi

+2

यदि आप "असेंबलर" के बारे में बात करते हैं, तो उन्हें सही तरीके से लागू करें। उन्हें मॉड्यूलर बनाएं, उन्हें आसानी से स्वीकार्य बनाएं, निर्भरता इंजेक्शन का उपयोग करें। डोमेन मॉडल को डीटीओ में रूपांतरण के बारे में जागरूक होने की आवश्यकता नहीं है। मान लीजिए कि मेरे पास 1 डोमेन ऑब्जेक्ट है लेकिन उसी डोमेन का उपयोग करके 50 अलग-अलग एप्लिकेशन हैं, जिनमें से प्रत्येक का अपना डीटीओ है। आप 50 एक्सटेंशन नहीं बनाने जा रहे हैं। इसके बजाय आप सेवा में निर्भरता के रूप में इंजेक्शन किए जाने वाले उत्तराधिकारी असेंबलरों के साथ प्रत्येक एप्लिकेशन के लिए एक आवेदन सेवा तैयार करेंगे। –

1

कैसे आप डीटीओ वर्ग कि एक पैरामीटर एक डोमेन वस्तु के रूप में लेता है अंदर एक निर्माता लागू करने के लिए देखते हैं?

कहते हैं ... इस तरह कुछ

class DTO { 

    // attributes 

    public DTO (DomainObject domainObject) { 
      this.prop = domainObject.getProp(); 
    } 

    // methods 
} 
+6

कृपया, यह कभी नहीं करें। आप नहीं चाहते हैं कि आपकी डीटीओ परत आपकी डोमेन परत पर जागरूक या निर्भर हो। मानचित्रण का लाभ यह है कि मैपिंग को बदलकर निचली परतों को आसानी से स्विच किया जा सकता है, या निचली परत में संशोधनों को मैपिंग बदलकर नियंत्रक हो सकता है। आइए आज डोमेनओब्जेक्टा पर dtoA मानचित्र कहें, लेकिन कल आवश्यकता यह है कि यह डोमेन ऑब्जेक्टबी पर मैप करता है। आपके मामले में आपको डीटीओ ऑब्जेक्ट को संशोधित करना होगा, जो एक बड़ा नो-नो है। आपने मैपर के बहुत सारे लाभ खो दिए हैं। –

+1

सबसे पहले, धन्यवाद! : डी। तो 'डीटीओ' और 'डोमेन ऑब्जेक्ट' के बीच एक परत डालने से @ फ्रेडरिक प्रिजैक, हम मूल रूप से डीटीओ की इस समस्या का प्रयास करते हैं, डोमेन ऑब्जेक्ट पर निर्भर करता है, इसलिए सभी "बिल्डिंग वर्क" को मध्यम परत (वर्ग) में किया जाता है जिसे ' मैपर ', जो दोनों डीटीओ और डोमेन ऑब्जेक्ट्स पर निर्भर है। तो यह सबसे अच्छा है, या आम तौर पर सिफारिश है, इस मामले के लिए दृष्टिकोण? मैं केवल यह सुनिश्चित करने के लिए कहता हूं कि बिंदु समझा गया था। – Victor

+4

हाँ, परत को "असेंबलर" कहा जाता है। मैपिंग को परिभाषित करने के लिए 3 वें परत का उपयोग करके आप असेंबलर परत को किसी अन्य कार्यान्वयन से आसानी से बदलने की संभावना देते हैं (उदाहरण: ऑटोमैपर को हटाएं और मैन्युअल मैपिंग का उपयोग करें), जो हमेशा बेहतर विकल्प होता है। इसे समझने का सबसे अच्छा तरीका यह है कि मैं आपको ऑब्जेक्ट ए कहां दूंगा, और कोई और आपको ऑब्जेक्ट बी देता है। आपके पास उन सभी ऑब्जेक्ट्स (केवल डीएलएल) तक पहुंच नहीं है, इसलिए मैपिंग केवल 3 वें बनाकर किया जा सकता है परत। लेकिन यहां तक ​​कि यदि आप किसी भी ऑब्जेक्ट तक पहुंच सकते हैं, तो मैपिंग हमेशा बाहर की जानी चाहिए, क्योंकि वे संबंधित नहीं हैं। –

0

क्यों नहीं हम इस तरह कर सकते हैं?

class UserDTO { 
} 

class AdminDTO { 
} 

class DomainObject { 

// attributes 
public DomainObject(DTO dto) { 
     this.dto = dto; 
}  

// methods 
public function isActive() { 
     return (this.dto.getStatus() == 'ACTIVE') 
} 

public function isModeratorAdmin() { 
     return (this.dto.getAdminRole() == 'moderator') 
} 

} 


userdto = new UserDTO(); 
userdto.setStatus('ACTIVE'); 

obj = new DomainObject(userdto) 
if(obj.isActive()) { 
    //print active 
} 

admindto = new AdminDTO(); 
admindto.setAdminRole('moderator'); 

obj = new DomainObject(admindto) 
if(obj.isModeratorAdmin()) { 
    //print some thing 
} 

@FrederikPrijck (या) किसी: कृपया सुझाव देते हैं। उपर्युक्त उदाहरण में DomainObject डीटीओ पर निर्भर करता है। इस तरह से मैं dto < -> डोमेनोबजेक्ट मैपिंग करने के लिए कोड से बच सकता हूं।

या डोमेन ऑब्जेक्ट क्लास डीटीओ कक्षा को बढ़ा सकता है?

संबंधित मुद्दे