आक्रमणकारी क्या हैं, उनका उपयोग कैसे किया जा सकता है, और क्या आपने कभी अपने कार्यक्रम में इसका उपयोग किया है?


48

मैं काम पर कोडर्स पढ़ रहा हूं , और इसमें बहुत से लोगों के बारे में बात की गई है। जहां तक ​​मैंने इसे समझा है, एक अपरिवर्तनीय एक ऐसी स्थिति है जो एक अभिव्यक्ति से पहले और बाद में दोनों रखती है। वे अन्य बातों के अलावा, यह साबित करने में उपयोगी हैं कि लूप सही है, अगर मुझे मेरा लॉजिक कोर्स सही ढंग से याद है।

क्या मेरा वर्णन सही है, या क्या मैंने कुछ याद किया है? क्या आपने कभी उन्हें अपने कार्यक्रम में इस्तेमाल किया है? और यदि हां, तो उन्हें लाभ कैसे हुआ?



@ रोबर्ट हार्वे: हाँ, मैं वास्तव में पढ़ता हूं। लेकिन यह मुझे लगता है कि जब आप कुछ साबित करने की कोशिश कर रहे हैं तो केवल उपयोगी हैं। क्या यह सही है (कोई सज़ा नहीं है)?
गैबलिन

यही मेरी समझ है; जब आप अपने कार्यक्रम के बारे में तर्क करने की कोशिश कर रहे हैं, तो इसकी शुद्धता को साबित करने के लिए।
रॉबर्ट हार्वे

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

1
सही साबित करने के लिए आक्रमणकारी वास्तव में उपयोगी हैं, लेकिन वे उस मामले तक सीमित नहीं हैं। वे रक्षात्मक-प्रोग्रामिंग और डीबगिंग के दौरान भी उपयोगी हैं। वे सिर्फ यह साबित करने में मदद नहीं करते हैं कि आपका कोड सही है, वे कोड के बारे में कारण की मदद करते हैं और मूल के करीब कीड़े का स्थान ढूंढते हैं।
Oddthinking

जवाबों:


41

ओओपी में, एक अपरिवर्तनीय दावा का एक सेट है जो हमेशा मान्य होने के लिए एक वस्तु के जीवन के दौरान सच होना चाहिए। जब भी ऑब्जेक्ट वर्तमान में ऐसी विधि को निष्पादित नहीं कर रहा होता है, तो यह विध्वंसक की शुरुआत से विध्वंसक के अंत तक सही होना चाहिए।

अपरिवर्तनीय का एक उदाहरण यह हो सकता है कि वास्तव में दो सदस्य चर में से एक शून्य होना चाहिए। या कि यदि किसी का दिया हुआ मूल्य है, तो दूसरे के लिए अनुमत मूल्यों का समूह यह है या वह ...

मैं कभी-कभी ऑब्जेक्ट के एक सदस्य फ़ंक्शन का उपयोग करके यह जांचता हूं कि इनवॉयरनेंट होल्ड है। यदि यह मामला नहीं है, तो एक जोर दिया जाता है। और प्रत्येक विधि के प्रारंभ और निकास पर विधि को कहा जाता है जो वस्तु को बदलता है (C ++ में, यह केवल एक पंक्ति है ...)


11
ए 1 का उल्लेख करने के लिए आक्रमणकारियों को एक निष्पादन विधि के बीच में सही नहीं होना चाहिए।
ओडिन्थंकिंग

1
@ जब भी संभव हो तो बचना सबसे अच्छा। आक्रमण करने वाले राज्य में प्रवेश करना आसान होगा और लौटने से पहले सब कुछ ठीक से बहाल करना भूल जाएंगे। अपवाद आपको परेशानी भी दे सकते हैं।
अलेक्जेंडर

3
@ अलेक्जेंडर: गैर-तुच्छ आक्रमणकारियों के लिए, से बचना लगभग असंभव है। यदि आपको एक विधि में एक से अधिक चर को अपडेट करने की आवश्यकता है, जैसा कि उत्तर में वर्णित है, तो एक बिंदु है जहां केवल एक को अपडेट किया गया है और अपरिवर्तनीय गलत है। नए लोगों को जोड़े बिना अच्छा कोड लिखने के लिए पर्याप्त बाधाएं हैं।
18:30 बजे

@ हाँ, यह अक्सर काफी अपरिहार्य है। लेकिन उदाहरण के लिए, यदि चर का एक समूह है जो तार्किक रूप से एक साथ हैं (उदाहरण के लिए एक सरणी, और "सरणी में" चयनित "आइटम का सूचकांक), तो यह संभवतः उन्हें एक प्रकार से निकालने के लायक है। वहाँ से, सरणी या प्रकार के उत्परिवर्तन को उस प्रकार के एक नए उदाहरण के एकल असाइनमेंट के रूप में व्यक्त किया जा सकता है
अलेक्जेंडर

13

ठीक है, मैं इस धागे में जो सामान देख रहा हूं, वह सब बहुत अच्छा है, लेकिन मेरे पास एक 'अपरिवर्तनीय' की परिभाषा है जो काम पर मेरे लिए बहुत मददगार रही है।

एक अपरिवर्तनीय कोई भी तार्किक नियम है जिसे आपके कार्यक्रम के निष्पादन के दौरान पालन किया जाना चाहिए जो कि एक मानव के लिए संचार किया जा सकता है, लेकिन आपके कंपाइलर को नहीं।

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

इसके अलावा, यह परिभाषा सहायक है क्योंकि यह आपको सामान्यीकरण का उपयोग करने की अनुमति देता है, "इनवेरिएंट खराब हैं"।

एक उदाहरण के रूप में, एक मैनुअल ट्रांसमिशन कार में शिफ्टर एक अपरिवर्तनीय से बचने के लिए इंजीनियर है। अगर मैं चाहता, तो मैं प्रत्येक गियर के लिए एक लीवर के साथ एक ट्रांसमिशन का निर्माण कर सकता था। यह लीवर आगे ("लगे") या पीछे ("अस्त-व्यस्त") हो सकता है। इस तरह की प्रणाली में, मैंने एक "अपरिवर्तनीय" बनाया है, जिसे इस तरह से प्रलेखित किया जा सकता है:

"यह महत्वपूर्ण है कि वर्तमान में लगे हुए गियर को एक अलग गियर लगे होने से पहले विघटित किया जाए। एक ही समय में किसी भी दो गियर को जोड़ने के लिए यांत्रिक तनाव का कारण होगा जो ट्रांसमिशन को अलग कर देगा। हमेशा दूसरे को उलझाने से पहले वर्तमान में लगे गियर को अलग करें।"

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

इस तरह, हम कह सकते हैं कि ट्रांसमिशन को 'इनवेरिएंट' को हटाने के लिए इंजीनियर किया गया है, क्योंकि यह खुद को यंत्रवत् रूप से कॉन्फ़िगर करने की अनुमति नहीं देता है जो तार्किक नियम का उल्लंघन करता है।

इस तरह का हर आवेग जिसे आप अपने कोड से हटाते हैं, एक सुधार है, क्योंकि यह इसके साथ काम करने के संज्ञानात्मक भार को कम करता है।


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

1
कार के गियर की तुलना मेरे लिए बहुत स्पष्ट है। धन्यवाद!
मर्के

"एक अपरिवर्तनीय कोई भी तार्किक नियम है जिसे आपके कार्यक्रम के निष्पादन के दौरान पालन किया जाना चाहिए जो कि एक मानव के लिए संप्रेषित किया जा सकता है, लेकिन आपके कंपाइलर को नहीं।" - मुझे यह पसंद है, संक्षिप्त और याद रखने में आसान है।
ZeroKnight

@DustinCleveland मुझे लगता है कि इस उदाहरण में, स्टिक शिफ्ट के पीछे के तंत्र 'संकलक' हैं जो नियमों को लागू करते हैं, जबकि ड्राइवर जो अन्यथा एक घटना का कारण हो सकता है, कई ग्राहकों में से एक है जिसे उपभोग करना चाहिए और उस जानकारी को याद रखना चाहिए। "प्रलेखित, चर्चा की गई, टिप्पणी की गई, या अन्यथा संचार किया गया।"
एबरनार्ड

शानदार व्याख्या! मैं वास्तव में अब समझता हूं कि आपके कोड में इनवेरिएंट होने का कारण खराब अभ्यास है।
बेन सी वांग

3

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


3

कोडर्स एट वर्क के निम्नलिखित उद्धरण के आधार पर ...

लेकिन एक बार जब आप यह सुनिश्चित कर लेते हैं कि आप इसे बनाए रख रहे हैं, तो आप देख सकते हैं, आह, अगर हम उस हमलावर को बनाए रखते हैं तो हमें लॉग लुकअप समय मिल जाएगा।

... मुझे लगता है कि "अपरिवर्तनीय" = "एक वांछित प्रभाव सुनिश्चित करने के लिए आप जिस स्थिति को बनाए रखना चाहते हैं"।

ऐसा लगता है कि इनवेरिएंट में दो इंद्रियां होती हैं जो सूक्ष्म तरीके से भिन्न होती हैं:

  1. कुछ ऐसा ही रहता है।
  2. लक्ष्य एक्स को प्राप्त करने के लिए आप कुछ ऐसा ही करने की कोशिश कर रहे हैं (जैसे कि "लॉग लुकअप टाइम" ऊपर)।

तो 1 एक जोर की तरह है; 2 शुद्धता, प्रदर्शन या अन्य गुणों को साबित करने के लिए एक उपकरण की तरह है - मुझे लगता है। 2 के उदाहरण के लिए विकिपीडिया लेख देखें (एमयू पहेली के समाधान की शुद्धता साबित करते हुए)।

वास्तव में अपरिवर्तनीय का तीसरा अर्थ है:

.3। प्रोग्राम (या मॉड्यूल या फ़ंक्शन) क्या करना चाहिए; दूसरे शब्दों में, इसका उद्देश्य।

कार्य साक्षात्कार में समान कोडर्स से:

लेकिन जो चीज बड़े सॉफ्टवेयर को मैनेज करती है वह कुछ वैश्विक आक्रमणकारियों या बड़े-पिक्चर स्टेटमेंट्स के बारे में बताती है कि यह क्या करना है और क्या चीजें सच मानी जाती हैं।


1

एक आक्रमणकारी एक नियम या एक धारणा की तरह है जिसका उपयोग आपके कार्यक्रम के तर्क को निर्धारित करने के लिए किया जा सकता है।

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

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

क्लास यूजरअकाउंट {प्राइवेट चार * pUserName; निजी चार * pParentAccountUserName;

...}

एक अपरिवर्तनीय धारणा यह हो सकती है कि यदि pParentAccountUserName NULL या खाली है तो यह ऑब्जेक्ट मूल खाता है। आप विभिन्न प्रकार के खाते को अलग करने के लिए इस अपरिवर्तनीय का उपयोग कर सकते हैं। विभिन्न प्रकार के उपयोगकर्ता खातों को अलग करने के लिए संभवतः बेहतर तरीके हैं, इसलिए ध्यान रखें कि यह केवल एक उदाहरण है कि यह दिखाने के लिए कि एक अपरिवर्तनीय का उपयोग कैसे किया जा सकता है।


आक्रमणकारी एक कार्यक्रम की स्थिति की जांच करते हैं। वे निर्णय डिजाइन नहीं कर रहे हैं।
जेवियर नोडेट

3
आक्रमणकारी कुछ भी जाँच नहीं करते हैं। आप यह देखने के लिए प्रोग्राम की स्थिति देख सकते हैं कि क्या कोई अपरिवर्तनीय TRUE या FALSE है, लेकिन आक्रमणकारी स्वयं कुछ नहीं करते हैं।
पेमदास

2
आमतौर पर, C ++ में आपको कुछ प्रकार के वर्ग इनवेरियन दिखाई देंगे जैसे कि सदस्य x 25 से कम और 0. से अधिक होना चाहिए। उस अपरिवर्तनीय के खिलाफ कोई भी जाँच दावे हैं। ऊपर दिए गए उदाहरण में, मेरा अपरिवर्तनीय है अगर pParentAccountUserName NULL या खाली है तो यह एक मूल खाता है। आक्रमणकारी डिजाइन किए गए निर्णय हैं।
पेमदास

आप कैसे चेक करते हैं कि यदि pParentAccountUserName NULL या खाली है, तो यह ऑब्जेक्ट पैरेंट अकाउंट है? आपका कथन केवल यह बताता है कि निरर्थक / रिक्त मान को किसका प्रतिनिधित्व करना है। अपरिवर्तनीय यह है कि सिस्टम उसी के अनुरूप है, अर्थात pParentAccountUserName केवल शून्य या रिक्त हो सकता है यदि यह एक मूल खाता है। यह एक सूक्ष्म अंतर है।
कैमरून

1

भौतिकी की पृष्ठभूमि से आने वाले, भौतिकी में हमारे पास अपरिवर्तनीय हैं, जो अनिवार्य रूप से मात्राएं हैं जो संपूर्ण गणना / सिमुलेशन में भिन्न नहीं होती हैं। उदाहरण के लिए, भौतिकी में, एक बंद प्रणाली के लिए कुल ऊर्जा संरक्षित है। या भौतिकी में फिर से, यदि दो कण टकराते हैं, तो परिणामी अंशों में ठीक वही ऊर्जा होनी चाहिए जो उन्होंने शुरू की थी, और ठीक उसी गति (एक वेक्टर मात्रा) के साथ। आमतौर पर परिणाम को पूरी तरह से निर्दिष्ट करने के लिए पर्याप्त आक्रामक नहीं होते हैं। उदाहरण के लिए 2 पार्टिकल टकराव में, हमारे पास चार इनवेरिएंट, तीन संवेग घटक और एक ऊर्जा घटक है, लेकिन सिस्टम में छह डिग्री की स्वतंत्रता (छह अवस्थाओं का वर्णन करने के लिए) है। हमलावरों को गोल त्रुटि के भीतर संरक्षित किया जाना चाहिए, लेकिन उनका संरक्षण यह साबित नहीं करता है कि समाधान सही है।

इसलिए आमतौर पर, ये चीजें पवित्रता की जाँच के रूप में महत्वपूर्ण हैं, लेकिन स्वयं के द्वारा वे शुद्धता साबित नहीं कर सकते हैं।


1
-1 भौतिक विज्ञान में भिन्न भिन्न हैं। एक समाधान की गणना करना यह साबित करने के समान नहीं है कि एक एल्गोरिथ्म सही है। उत्तरार्द्ध के लिए, आक्रमणकारी शुद्धता साबित कर सकते हैं
एरोनस्टरलिंग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.