क्या मैं यह सोचने में गलत हूं कि ऑटोमैपर जैसी किसी चीज की जरूरत खराब डिजाइन का संकेत है?


35

आटोमैपर .Net के लिए एक "ऑब्जेक्ट-ऑब्जेक्ट मैपर" है, जिसका अर्थ है कि एक वर्ग से दूसरे वर्ग में वस्तुओं की नकल करना जो एक ही चीज़ का प्रतिनिधित्व करता है।

यह कभी क्यों उपयोगी है? क्या कक्षाओं का दोहराव कभी उपयोगी / अच्छा डिज़ाइन है?


थोड़ा संदर्भ: devtrends.co.uk/blog/… विशेष रूप से अनुभाग पढ़ें "हम ऑटोमैपर का उपयोग क्यों नहीं कर सकते?"
जानी हयातीनन

जवाबों:


28

एक त्वरित Google खोज ने इस उदाहरण को प्रकट किया:

http://www.codeproject.com/Articles/61629/AutoMapper

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

ऐसी स्थिति में आपकी "दृश्य वस्तुएं" मूल वर्ग की नकल नहीं हैं। उनके पास अलग-अलग तरीके हैं और शायद कुछ डुप्लिकेट विशेषताएँ हैं। लेकिन यह ठीक है कि जब तक आप केवल यूआई प्रदर्शन उद्देश्यों के लिए उस दृश्य वस्तुओं का उपयोग करते हैं और डेटा हेरफेर या व्यावसायिक कार्यों के लिए उनका दुरुपयोग शुरू नहीं करते हैं।

एक और विषय जिसे आप पढ़ सकते हैं, यह समझने के लिए बेहतर है कि फाउडर्स कमांड क्वेरी रिस्पॉन्सिबिलिटी सेग्रीगेशन पैटर्न, सीआरयूडी के विपरीत है। यह उन स्थितियों को दिखाता है जहां डेटा को क्वेरी करने और उन्हें डेटाबेस में अपडेट करने के लिए विभिन्न ऑब्जेक्ट मॉडल समझ में आते हैं। यहाँ, AutoMapper जैसे टूल द्वारा एक ऑब्जेक्ट मॉडल से दूसरे में मैपिंग भी की जा सकती है।


1
अपने पहले उदाहरण के बारे में: क्या आप वस्तुओं की नकल करने के बजाय उनकी रचना नहीं कर सकते? उस स्थिति में आपके UI ऑब्जेक्ट्स में आपके मूल डेटा ऑब्जेक्ट का संदर्भ होगा, और केवल आवश्यक तत्वों को उजागर करेगा। यह समझ में नहीं आता है?
static_rtti 13

1
सिद्धांत में @static_rtti हाँ, लेकिन आप जरूरी नहीं चाहते कि आपकी मूल कक्षा सार्वजनिक हो या / और एक विधानसभा में उजागर हो
Jalayn

2
@static_rtti: हाँ, यह पूरी तरह से मान्य, अलग दृष्टिकोण है। उन दो डिज़ाइनों के बीच मुख्य अंतर डेटा / विशेषताओं का जीवनकाल है। प्रतियों का उपयोग आपको डेटा का एक स्नैपशॉट प्रदान करता है, मूल डेटा को संदर्भित करने वाले गुणों का उपयोग नहीं करता है। दोनों दृष्टिकोणों के पास इसके पेशेवरों और विपक्ष हैं, लेकिन आईएमएचओ सामान्य रूप से "बेहतर या बदतर" नहीं है। इसके अतिरिक्त, प्रदर्शन के विचार हो सकते हैं, जो निर्णय का उपयोग करने के लिए प्रभावित कर सकते हैं या नहीं भी कर सकते हैं।
डॉक्टर ब्राउन

3
जितना संभव हो उतना कम करना हमेशा एक अच्छा विचार है। इसलिए नहीं कि यह विशेष रूप से छोटी परियोजनाओं के लिए भी फायदेमंद है, बल्कि इसलिए कि परियोजनाएँ बढ़ती हैं।
तमसे सजेलेई

6
@ मछली: मैं ज्यादातर सहमत हूं, डिकॉउलिंग अक्सर एक अच्छा विचार होता है, लेकिन आईएमएचओ में पर्याप्त परिस्थितियां होती हैं, जहां चीजों को सरल बनाना एक मल्टी-लेयर-सुपर-डिकॉपल्ड-फॉर-द-द-डिकॉपिंग दृष्टिकोण है। कठिन हिस्सा किसी परियोजना की वृद्धि के दौरान बिंदु को याद नहीं करना है, जब किसी को फिर से शुरू करना चाहिए।
डॉक्टर ब्राउन

45

क्या कक्षाओं का दोहराव कभी उपयोगी / अच्छा डिज़ाइन है?

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

जहाँ तक AutoMapper का उपयोग करने की बात है, मैं व्यक्तिगत रूप से 3 कारणों से इससे बचता हूँ:

मौन विफलता अधिक सामान्य है

क्योंकि AutoMapper स्वचालित रूप से गुणों के बीच मैप करता है, एक वर्ग पर एक संपत्ति का नाम बदल रहा है और दूसरा नहीं जिससे संपत्ति मैपिंग को छोड़ दिया जाएगा। संकलक को पता नहीं चलेगा। Automapper परवाह नहीं करेगा।

स्थिर विश्लेषण का अभाव

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

देर से आवश्यकताएं जो जटिलता को बढ़ाती हैं

आटोमैपर सभी ठीक है और बांका है जब आप सभी करना चाहते हैं तो एक वर्ग से दूसरे में मूल्यों को कॉपी करें (जैसा कि अक्सर विकास के START पर मामला होता है), लेकिन उन आवश्यकताओं को याद रखें जो समय के साथ बदलते हैं? यदि आपको अब अपने एप्लिकेशन के अन्य हिस्सों से मान प्राप्त करने की आवश्यकता है, तो शायद उस उपयोगकर्ता के लिए विशिष्ट है जो लॉग इन या किसी अन्य संदर्भ स्थिति में है?

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

सारांश में, अपने आप को 30 सेकंड तक मैन्युअल रूप से सहेजने से पहले एक कक्षा से दूसरे वर्ग को मैप करने के लिए ऑटोमैपर तक पहुंचने से पहले, इस बारे में सोचें।

प्रोग्रामिंग दूसरे मानव को यह बताने की कला है कि कंप्यूटर क्या करना चाहता है। - डोनाल्ड नथ

इसे ध्यान में रखते हुए, अपने आप से पूछें "आज AutoMapper सहायक है और क्या यह कल होगा?"


[अगर आप ट्रेंडी वेब देव करते हैं] तो यदि आप एक REST वेब सेवा लिख ​​रहे हैं, तो क्या आप यह सुनिश्चित करने के लिए कि आपके जावास्क्रिप्ट ऑब्जेक्ट मॉडल आपके .NET ऑब्जेक्ट मॉडल के अनुरूप है, यह सुनिश्चित करने के लिए आप प्रत्येक संपत्ति की हमेशा जांच करते हैं?
डेन

3
@ देखा - हाँ। और आप यह सुनिश्चित करने के लिए परीक्षण लिखते हैं कि आपको सभी गुण सही मिलेंगे (अर्थात आपका परीक्षण किसी भी गुण को दिखाएगा जो आपने 1 स्थान पर जोड़ा है जो अन्य स्तरों पर प्रचारित नहीं होता है)
gbjbaanb

@gbjananb मैं शायद केवल एक सामान्य तरीके से इस सत्यापन को करने के लिए प्रतिबिंब का उपयोग करूंगा। शायद कुछ मान्यता जोड़ने के लिए AutoMapper के विस्तार की संभावना का पता लगाएं। निश्चित रूप से बहुत सारे मैनुअल असाइनमेंट से बचना चाहिए ।
डेन

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

21

मेरे अनुभव में, जब किसी ने 'बहुत अधिक बॉयलरप्लेट' के बारे में शिकायत की है और ऑटोमैपर का उपयोग करना चाहता है, तो यह निम्नलिखित में से एक है:

  1. उन्हें एक ही कोड को बार-बार लिखना चिढ़ लगता है।
  2. वे आलसी हैं और कोड लिखना नहीं चाहते हैं जो कि एक्स = बीएक्स करता है
  3. वे वास्तव में बहुत अधिक समय के दबाव में हैं कि क्या एक्स = बीएक्स पर लिखना एक अच्छा विचार है और फिर कार्य के लिए अच्छा कोड लिखना है।

तथापि:

  1. यदि यह वास्तव में पुनरावृत्ति से बचने के बारे में है, तो आप इसे सार करने के लिए एक वस्तु या विधि बना सकते हैं। आपको AutoMapper की आवश्यकता नहीं है।
  2. यदि आप आलसी हैं, तो आप आलसी होंगे और सीखेंगे नहीं कि AutoMapper कैसे काम करता है। इसके बजाय आप 'संयोग से प्रोग्रामिंग' पैटर्न को अपनाएंगे और एक भयानक कोड लिखेंगे जहाँ आप ऑटोमेपर प्रोफाइल में व्यावसायिक तर्क देते हैं। इस मामले में, आपको प्रोग्रामिंग के प्रति अपना दृष्टिकोण बदलना चाहिए या पेशे के रूप में कुछ और करना चाहिए। आपको AutoMapper की आवश्यकता नहीं है।
  3. यदि आप बहुत अधिक दबाव में हैं, तो आपकी समस्या का प्रोग्रामिंग से कोई लेना-देना नहीं है। आपको AutoMapper की आवश्यकता नहीं है।

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

इसके अलावा, सिर्फ इसलिए कि Microsoft ने C # में सुविधाओं को जोड़ा है, इसका मतलब यह नहीं है कि वे हर स्थिति में निष्पक्ष खेल हैं या वे सर्वश्रेष्ठ अभ्यास का समर्थन करते हैं। परावर्तन और 'डायनामिक' कीवर्ड, उदाहरण के लिए, उन मामलों में उपयोग किया जाना चाहिए जहां आप बस उनके बिना क्या जरूरत को पूरा नहीं कर सकते। AutoMapper किसी भी उपयोग के मामले के लिए एक समाधान नहीं है जो पहले से ही इसके बिना हल नहीं किया जा सकता है।

तो, क्या वर्गों का दोहराव खराब डिजाइन है? जरुरी नहीं।

क्या AutoMapper एक बुरा विचार है? हाँ बिल्कुल।

AutoMapper का उपयोग परियोजना में प्रणालीगत कमियों को इंगित करता है। यदि आप अपने आप को इसकी आवश्यकता पाते हैं, तो रोकें और अपने डिजाइन के बारे में सोचें। आपको हमेशा एक बेहतर, अधिक पठनीय, अधिक रख-रखाव और अधिक बग-मुक्त डिज़ाइन मिलेगा।


1
अच्छी तरह से कहा जाता है, विशेष रूप से 2.
मर्दोक्स

2
मुझे पता है कि यह बहुत पुराना धागा है, लेकिन मुझे इससे असहमत होना है। आप अमूर्त मानचित्रण की विधि नहीं बना सकते। आप 1 वर्ग के लिए कर सकते हैं, लेकिन अगर आपके पास 2 हैं, तो आपको 2 तरीके चाहिए। 3 - 3 विधियाँ। AM के साथ यह कोड की 1 पंक्ति है - मानचित्रण की परिभाषा। इसके अलावा, मैं वास्तव में एक परिदृश्य के साथ संघर्ष कर रहा था, जहां मेरे पास एक सूची थी <बेसटाइप> 10 सबटाइप डीटीओ से भरा। जब आप वह मैप करना चाहते हैं, तो आपको टाइप ऑन और फील्ड वैल्यू को कॉपी करने के लिए एक स्विच की आवश्यकता होती है। और क्या होगा अगर खेतों में से एक को अलग से मैप किया जाना है? यदि आपके पास कुछ सरल कक्षाएं हैं तो आपका उत्तर केवल अच्छा है। AutoMapper अधिक जटिल परिदृश्यों में जीत हासिल करता है।
user3512524

1
(चार्ली लिमिट) AM मुझे लगता है कि केवल एक वर्ग में संपत्ति के नाम को बदलने की संभावना है, दूसरे में नहीं। लेकिन वास्तव में, आप कितनी बार ऐसा करते हैं कि डिजाइन किए जाने के बाद? और आप एक सामान्य परीक्षण विधि लिख सकते हैं जो प्रतिबिंब का उपयोग करता है और संपत्ति के नामों की तुलना करता है। सभी उपकरणों की तरह, एएम को सही तरीके से उपयोग करना होगा - नेत्रहीन रूप से नहीं, सभी स्थितियों में नहीं, मैं सहमत हूं। लेकिन "आपको इसका उपयोग नहीं करना चाहिए" कहना गलत है।
user3512524

7

यहाँ एक गहरा मुद्दा है: तथ्य यह है कि C # और Java अधिकांश / सभी प्रकारों को संरचना के बजाय नाम से भिन्न होना चाहिए: उदाहरण के लिए class MyPoint2Dऔर class YourPoint2Dअलग-अलग प्रकार हैं भले ही उनकी सटीक परिभाषाएँ हों। जब आप चाहते हैं कि "एक xक्षेत्र और एक yक्षेत्र के साथ कुछ गुमनाम चीज " (यानी एक रिकॉर्ड ) है, तो आप भाग्य से बाहर हैं। इसलिए जब आप एक YourPoint2Dको एक में बदलना चाहते हैं MyPoint2D, तो आपके पास तीन विकल्प हैं:

  1. की तर्ज पर कुछ थकाऊ, दोहराव, सांसारिक बॉयलरप्लेट लिखें this.x = that.x; this.y = that.y
  2. किसी तरह कोड उत्पन्न करें।
  3. प्रतिबिंब का उपयोग करें।

चॉइस 1 छोटी खुराकों में काफी आसान है, लेकिन जल्दी से एक कोर बन जाता है जब आपको मैप करने के लिए आवश्यक प्रकारों की संख्या बड़ी होती है।

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

जो आपको प्रतिबिंब के साथ छोड़ देता है। आप इसे स्वयं कर सकते हैं, या आप AutoMapper का उपयोग कर सकते हैं।


3

ऑटोमैपर उन पुस्तकालयों / उपकरणों में से एक है जहां सम्राट सचमुच बट नग्न के आसपास चल रहा है। जब आप glitzy लोगो को पा लेते हैं, तो आपको एहसास होता है कि आप ऐसा कुछ भी नहीं कर सकते जो आप स्वयं बेहतर परिणामों के साथ नहीं कर सकते।

हालांकि मुझे पूरी तरह से यकीन नहीं है कि यह ऑटो-मैपिंग सदस्यों पर कैसे संकेत देता है, लेकिन इसमें सबसे अधिक संभावना अतिरिक्त रनटाइम लॉजिक और संभावित प्रतिबिंब शामिल है। यह समय की बचत के बदले एक महत्वपूर्ण प्रदर्शन जुर्माना हो सकता है। दूसरी ओर मैनुअल मैपिंग, संकलन समय से पहले संकेत को अच्छी तरह से निष्पादित किया जाता है।

ऐसे मामलों में जहां AutoMapper का कोई सुराग नहीं है, आपको कोड और सेटिंग झंडे के साथ मैपिंग को कॉन्फ़िगर करना होगा। यदि आप सभी सेटअप और कोड काम करने से परेशान हैं, तो आपको सवाल करना होगा कि यह मैनुअल मैपिंग पर कितना बचाता है।

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