2008-10-08 18 views
5

मेरे पास एक ऑब्जेक्ट है जिसे मैं एक विधि कॉल में गुजर रहा हूं। मान लें कि मैं ऐसी भाषा का उपयोग कर रहा हूं जो आपको केवल जावा या PHP जैसे संदर्भों से ऑब्जेक्ट पास करने की अनुमति देता है। यदि विधि ऑब्जेक्ट में परिवर्तन करता है, तो यह कॉलर को प्रभावित करेगा। मैं नहीं चाहता कि यह हो। तो ऐसा लगता है कि मुझे वस्तु की प्रतिलिपि बनाना है।ऑब्जेक्ट की विधि की प्रतिलिपि प्रतिलिपि - प्रतिलिपि कौन करता है?

मेरा प्रश्न है: ऑब्जेक्ट क्लोन करना किसकी ज़िम्मेदारी है? कॉलर, इससे पहले कि यह विधि बुलाता है? या कैली, इससे पहले वस्तु बदल जाती है?

संपादित करें: बस स्पष्ट करने के लिए, मैं चाहता हूं कि यह इस विधि के अनुबंध का हिस्सा बन जाए - कि यह मूल वस्तु को कभी भी संशोधित नहीं करता है। तो ऐसा लगता है कि यह प्रतिलिपि बनाने के तरीके पर होना चाहिए। लेकिन फिर कॉलर के पास ऐसी विधि से कोई सुरक्षा नहीं है जो ठीक से ऐसा नहीं करती है। मुझे लगता है कि यह स्वीकार्य है - यह एकमात्र अन्य विकल्प है जो इसे भाषा में बनाया गया है।

+0

मुझे यह समझ में नहीं आता। आपके पास एक ऐसी विधि है जो किसी ऑब्जेक्ट में परिवर्तन करती है, लेकिन विधि का निहित अनुबंध यह है कि यह नहीं करता है। क्या आप इसे और स्पष्ट कर सकते हैं? –

+0

विधि कॉलर के ऑब्जेक्ट को प्रभावित नहीं करना चाहिए, लेकिन यह ऑब्जेक्ट की अपनी प्रति बदल सकती है। –

उत्तर

0

निर्भर करता है, क्या कोई कारण है कि भविष्य में विधि को बुलाया जा सकता है जहां आप कॉलर द्वारा परिवर्तन को देखना चाहते हैं? यदि ऐसा है तो कॉलर को प्रतिलिपि बनाना चाहिए। अन्यथा कैली इसे बनाना चाहिए। मैं कहूंगा कि दूसरा मामला शायद अधिक आम है।

5

आम तौर पर, कॉलर को प्रतिलिपि बनाना चाहिए यदि यह में परिवर्तन के बारे में चिंतित है। यदि कॉलर परवाह नहीं है, विधि को प्रतिलिपि बनाना चाहिए यदि उसे ऐसा कुछ करने की आवश्यकता है जो जानता है कि जारी नहीं रहना चाहिए।

0

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

0

मेरी पहली प्रतिक्रिया यह होगी कि यह कॉलर की ज़िम्मेदारी है, लेकिन मुझे लगता है कि यह वास्तव में निर्भर करता है।

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

1

कॉलर। क्योंकि, कभी-कभी आप ऑब्जेक्ट में स्वयं और दूसरी बार प्रतिलिपि में परिवर्तन करना चाहते हैं।

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

संपादित करें (अपने के बाद): उस मामले में यह अनुबंध लागू करने के लिए कॉल प्राप्त करने वाला की जिम्मेदारी है, इसलिए वहाँ दो विकल्प हैं:

  • कॉल प्राप्त करने वाला बस वस्तु
  • या कॉल प्राप्त करने वाला प्रतियां संशोधित नहीं करता है वस्तु और प्रतिलिपि बाद में
+0

यह सही लगता है, कि यह कैली का अनुबंध है, और इसलिए इसकी ज़िम्मेदारी है। लेकिन फिर क्या हम इसे बहुत अधिक शक्ति नहीं दे रहे हैं, और इसे encapsulating नहीं? अब यह अपने आप से बाहर नुकसान कर सकता है। –

+0

यदि यह सुनिश्चित करके अनुबंध पूरा करता है कि कोई पारित वस्तुओं को संशोधित नहीं किया गया है तो कोई दुष्प्रभाव नहीं हैं और कोई नुकसान नहीं हुआ है। –

1

तो तुम = नए MyObject तरह

MyObject मीटर कुछ करना चाहता हूँ के साथ काम करता(); MyObject n = MyObjectProcessor.process (m) ;?

MyObject n = MyObjectProcessor.alter (m।) जैसे कुछ ऐसा करने के लिए मुझे लगता है।क्लोन());

जहां यह स्पष्ट है कि कौन कर रहा है। आप तर्क कर सकता है कि प्रोसेसर वर्ग समारोह दुष्प्रभाव से मुक्त होना चाहिए, जैसे कि यह एक नई वस्तु किसी भी समय यह स्थिति बदलने जा रहा है लौट जाना चाहिए, लेकिन (AFAIK) के रूप में कार्यात्मक प्रोग्रामिंग करने का विरोध किया OO में तो लगातार पीछा नहीं है।

उपरोक्त की तरह कुछ शायद हानिरहित है, जब तक कि इसे स्पष्ट रूप से नामित और दस्तावेज किया गया हो।

1

हम मार्गदर्शन के लिए रूबी को देख सकते थे। वे एक का उपयोग करते हैं! इंगित करने के लिए प्रतीक कि एक वस्तु जगह में संशोधित है। तो, pay.add (10000) एक नई वस्तु देता है लेकिन pay.add! (10000) मूल वस्तु देता है लेकिन संशोधित। स्थानीय नामकरण सम्मेलन का उपयोग करके आप जावा या PHP में एक ही विचार का उपयोग कर सकते हैं।

0

मैं कैली कहूंगा: यह कॉल को सरल बनाता है और कॉलर को दिए गए ऑब्जेक्ट्स की अखंडता के लिए चिंता करने की आवश्यकता नहीं होगी। अखंडता को संरक्षित रखने के लिए कैली की ज़िम्मेदारी है।

0

मुझे लगता है कि आपके पास स्थिर घोषणा की तरह कुछ होगा। यह संकलक लागू होगा और आपकी वस्तुओं की प्रतियां बनाने से अधिक कुशल होगा।

0

मुझे लगता है कि कॉलर को क्लोन बनाना चाहिए, बस नामकरण को आसान बनाना। आप CloneBarAndFooClone() के बजाय अपनी विधि Foo() का नाम दे सकते हैं।

की तुलना करें:

void RemoveZeroDollarPayments(Order order) 

बनाम

Order CloneOrderAndRemoveZeroDollarPaymentsFromClone(Order order) 
0

तो वस्तु में बदलाव नहीं कर विधि अनुबंध का हिस्सा है, केवल संभावना होने प्रतिलिपि विधि के अंदर किया जाता है। अन्यथा आप अपने ग्राहक से झूठ बोल रहे हैं।

तथ्य यह है कि आपको वास्तव में किसी ऑब्जेक्ट को संशोधित करने की आवश्यकता है जैसा कि आपको दिया गया है, केवल एक कार्यान्वयन विवरण है जिसे कॉलर पर बोझ नहीं डालना चाहिए। वास्तव में, उसे इसकी दृश्यता भी देखने की आवश्यकता नहीं है।

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