क्या जानकारी एक सम्मेलन से अधिक छिपा रही है?


20

जावा, C # और कई अन्य दृढ़ता से टाइप की गई, स्टेटिकली चेक की गई भाषाओं में, हमें इस तरह कोड लिखने के लिए उपयोग किया जाता है:

public void m1() { ... }
protected void m2() { ... }
private void m2() { ... }
void m2() { ... }

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

_m(self): pass

यह तर्क दिया जा सकता है कि गतिशील रूप से जाँच की गई भाषाओं में ऐसे कीवर्ड प्रदान करने से बहुत कम उपयोग होगा क्योंकि यह केवल रनटाइम पर जाँच की जाती है।

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

इसे ध्यान में रखते हुए, मेरा प्रश्न है:

क्या प्रोग्रामर्स के बीच एक कन्वेंशन से अधिक जानकारी को यह परिभाषित करने के लिए उपयोग किया जाता है कि किसी वर्ग के आधिकारिक इंटरफ़ेस का हिस्सा क्या है?

क्या इसका इस्तेमाल किसी वर्ग के गुप्त राज्य पर हमला करने से सुरक्षित करने के लिए किया जा सकता है? क्या प्रतिबिंब इस तंत्र को ओवरराइड कर सकता है? क्या यह सार्थक होगा संकलक करने के लिए लागू जानकारी छुपा?


10
क्षमा करें, एरिक
लिपर्ट

आपका सवाल समझना थोड़ा मुश्किल है। क्या आप मूल रूप से सिर्फ यह पूछ रहे हैं कि क्या कोई बाहर से निजी सदस्य का उपयोग कर सकता है?
मॉर्गन हेरलॉकर

1
संबंधित प्रश्न: programmers.stackexchange.com/questions/92380/…
user281377

@ironcode: मैं बता सकता हूं कि मैं किसी तरह खुद को कुछ उत्तरों से स्पष्ट रूप से व्यक्त नहीं करता। क्या आप बता सकते हैं कि विशेष रूप से इसे समझना कितना कठिन है? मैं स्पष्ट करने की कोशिश करूंगा।
blubb

2
"संकलन समय पर जानकारी प्रदान करना और फिर केवल रनटाइम पर जाँच करना बकवास है" - वास्तव में? बेहतर है कि Microsoft को बताएं क्योंकि वर्तमान .NET फ्रेमवर्क का एक महत्वपूर्ण हिस्सा इस पर आधारित है: चुनिंदा ऑपटिंग-इन या स्टैटिक टाइपिंग का विकल्प। मुझे नहीं लगता कि यह वास्तव में है, हालांकि आपका क्या मतलब है; सवाल बार-बार "स्थिर" बनाम "गतिशील" जाँच के बारे में बात करता है, लेकिन वे प्रकार प्रणाली की विशेषताएं हैं; यहाँ वास्तव में क्या समस्या है संकलन-समय बनाम रन-टाइम बाइंडिंग
एरॉन

जवाबों:


4

मैं जावा प्रमाणन के लिए अध्ययन कर रहा हूं और इसका एक पूरा गुच्छा इस बात की चिंता करता है कि, एक्सेस मॉडिफायर का प्रबंधन कैसे किया जाए। और वे समझ में आते हैं और उनका उचित उपयोग किया जाना चाहिए।

मैंने अजगर के साथ काम किया है और, अपनी सीखने की यात्रा के दौरान, मैंने सुना है कि अजगर में, सम्मेलन वहाँ है क्योंकि लोग, जो इसके साथ काम करते हैं, उन्हें पता होना चाहिए कि इसका क्या मतलब है और इसे कैसे लागू किया जाए। उस ने कहा, _m(self): passअंडरस्कोर में मुझे उस क्षेत्र के साथ खिलवाड़ नहीं करने के लिए सतर्क करेगा। लेकिन क्या हर कोई उस सम्मेलन का पालन करेगा? मैं जावास्क्रिप्ट के साथ काम करता हूं और मुझे कहना होगा, वे नहीं करते हैं । कभी-कभी मुझे एक समस्या की जांच करने की आवश्यकता होती है और इसका कारण यह था कि व्यक्ति कुछ ऐसा कर रहा था जिसे वह करने वाला नहीं था ...

अजगर अग्रणी अंडरस्कोर के बारे में इस चर्चा को पढ़ें

क्या प्रोग्रामर्स के बीच एक कन्वेंशन से अधिक जानकारी को यह परिभाषित करने के लिए उपयोग किया जाता है कि किसी वर्ग के आधिकारिक इंटरफ़ेस का हिस्सा क्या है?

मैंने जो कहा, उससे।

क्या इसका इस्तेमाल किसी वर्ग के गुप्त राज्य पर हमला करने से सुरक्षित करने के लिए किया जा सकता है? क्या प्रतिबिंब इस तंत्र को ओवरराइड कर सकता है? क्या कंपाइलर द्वारा लागू किए गए अधिक औपचारिक तंत्र द्वारा प्रदान किए गए अन्य लाभ हैं?

हाँ, इसका उपयोग एक वर्ग की गुप्त स्थिति को सुरक्षित करने के लिए किया जा सकता है और इसका उपयोग न केवल इसके लिए किया जाना चाहिए, बल्कि उपयोगकर्ताओं को वस्तुओं के राज्य के साथ खिलवाड़ करने से रोकने के लिए उनके व्यवहार को कुछ ऐसा करने के लिए बदलना चाहिए जो उन्हें लगता है कि जिस तरह से वस्तु होनी चाहिए। काम करना। आपको एक डेवलपर के रूप में योजना बनानी चाहिए और इसके बारे में सोचना चाहिए और अपनी कक्षा को इस तरह से डिजाइन करना चाहिए जो समझ में आए, इस तरह से कि उसके व्यवहार में छेड़छाड़ नहीं की जाएगी। और संकलक, एक अच्छे दोस्त के रूप में, आपको कोड को उस तरीके से रखने में मदद करेगा, जिस तरह से आपने इसे डिज़ाइन किया था।

संपादित हां, प्रतिबिंब, टिप्पणियों की जांच कर सकते हैं

आखिरी सवाल एक दिलचस्प है और मैं इसके बारे में जवाब पढ़ने के लिए तैयार हूं।


3
परावर्तन आमतौर पर पहुँच सुरक्षा को बायपास कर सकता है। जावा और C # के लिए, वे दोनों निजी डेटा तक पहुंच सकते हैं।
मार्क एच

धन्यवाद! यहाँ उत्तर: stackoverflow.com/questions/1565734/… इसे समझाएं!
वुल्मो

1
जावास्क्रिप्ट संस्कृति अजगर संस्कृति से बहुत अलग है। पायथन में पेप -08 है और लगभग सभी अजगर डेवलपर्स इन सम्मेलनों का पालन करते हैं। पीईपी -08 उल्लंघन अक्सर बग के रूप में माना जाता है। तो मुझे लगता है कि जावास्क्रिप्ट / php / perl / माणिक अनुभव इस पहलू में बहुत कम अजगर के अनुभव में अनुवाद करता है: _प्रीथ अजगर में बहुत अच्छी तरह से काम करता है।
माइक कोरोबोव

1
कुछ (लेकिन सभी नहीं) प्रोग्रामिंग भाषाओं में, शत्रुतापूर्ण कोड से बचाने के लिए सूचना छिपाने का उपयोग किया जा सकता है। शत्रुतापूर्ण उपयोगकर्ताओं से बचाव के लिए सूचना छिपाने का उपयोग नहीं किया जा सकता है।
ब्रायन

2
@ माइक अगर PEP-08 के उल्लंघन को अक्सर "बग के रूप में माना जाता है", और कोई पायथन देव सम्मेलनों का पालन नहीं करने का सपना देखता है, तो आप उन्हें भाषा द्वारा लागू कर सकते हैं! जब भाषा अपने आप ऐसा कर सकती है तो पुरुषवादी काम क्यों करते हैं?
एंड्रेस एफ।

27

"निजी" एक्सेस स्पेसियर कंपाइलर त्रुटि के बारे में नहीं है जो आप इसे पहली बार देखते हैं। वास्तव में यह आपको किसी ऐसी चीज को एक्सेस करने से रोकने के बारे में है जो तब भी बदलती है जब निजी सदस्य रखने वाले वर्ग के कार्यान्वयन में परिवर्तन होता है।

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

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

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

तो, संक्षिप्त पुनर्कथन:

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

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

3
@ साइमन स्टेलिंग - नहीं, मैं कह रहा हूं कि कुछ नया करने वाले वर्ग का मूल कार्यान्वयन आपको बता रहा है "इसका उपयोग न करें, यहां कोई भी व्यवहार भविष्य में बदल सकता है"। उदाहरण के लिए, एक वर्ग का एक निजी सदस्य चर जिसमें पहले दो बिंदुओं के बीच की दूरी होती है, बाद में प्रदर्शन कारणों से दो बिंदुओं के बीच की दूरी हो सकती है। पुराने व्यवहार पर भरोसा करने वाली कोई भी बात चुपचाप टूट जाती।
जॉरिस टिम्मरमन्स

1
@MadKeithV: फिर एक भाषा-स्तरीय कीवर्ड यह कैसे कह रहा है कि "स्पर्श न करें क्योंकि ..." एक कन्वेंशन से अलग एक ही अर्थ है? केवल संकलक ही इसे लागू कर रहा है, लेकिन फिर हम तु पुराने बनाम स्थैतिक बनाम गतिशील चर्चा के लिए वापस आ रहे हैं।

7
@Simon स्टेलिंग (और डेलन) - मेरे लिए यह पूछने की तरह है कि "एक गति सीमा संकेत से अलग इंजन लिमिटर कैसे है"।
जॉरिस टिम्मरमन्स

1
मैं अंतर से अच्छी तरह वाकिफ हूं और मैंने कभी नहीं कहा कि यह नहीं था। मुझे लगता है कि आपका उत्तर और आपकी अधिकांश अनुवर्ती टिप्पणियां केवल सदस्यों और विधियों के लिए टिप्पणियों के प्रकारों का वर्णन करती हैं जो सम्मेलनों या भाषा-स्तरीय कीवर्ड के साथ किए जा सकते हैं और वास्तविक अंतर (लैनगेज-स्तरीय प्रवर्तन की उपस्थिति) को छोड़ सकते हैं पाठक से प्रभावित।

11

यदि आप ऐसा कोड लिख रहे हैं जो किसी और के द्वारा उपभोग किया जाएगा, तो जानकारी छिपाना इंटरफ़ेस को आसान बनाने के लिए बहुत आसान प्रदान कर सकता है। "कोई और" आपकी टीम पर एक और डेवलपर हो सकता है, डेवलपर्स एक एपीआई का उपभोग करते हैं, जिसे आपने व्यावसायिक रूप से लिखा था, या यहां तक ​​कि आपके भविष्य के स्वयं ने भी लिखा था कि "बस यह याद नहीं कर सकता कि कैसे खतरे काम करता है"। एक वर्ग के साथ काम करना आसान है जिसमें 40 की तुलना में केवल 4 विधियाँ उपलब्ध हैं।


2
मैं पूरी तरह सहमत हूं, लेकिन यह मेरे सवाल का जवाब नहीं देता है। चाहे मैं उपयोग करूं _memberया private memberमेरी कक्षा में नगण्य है, जब तक कि अन्य प्रोग्रामर यह समझता है कि उसे केवल publicगैर-पूर्वनिर्धारित सदस्यों को देखना चाहिए ।
ब्लूब

6
हां, लेकिन एक गतिशील भाषा में लिखे गए वर्ग के सार्वजनिक दस्तावेज उन 36 निजी हिस्सों को या तो आप पर नहीं फेंकते हैं (कम से कम डिफ़ॉल्ट रूप से नहीं)।

3
@ साइमन का कथन है कि यह "सिर्फ एक सम्मेलन" भ्रामक है, क्योंकि इसके वास्तविक लाभ हैं। "बस एक सम्मेलन" अगली पंक्ति में घुंघराले ब्रेसिज़ की तरह है। लाभ के साथ एक सम्मेलन कुछ सार्थक नामों का उपयोग करने जैसा है, जो मैं कहूंगा कि यह पूरी तरह से अलग है। क्या किसी को निजी सेट करने से आपको "गुप्त तरीकों" को देखने से किसी को रोकना पड़ता है? नहीं, नहीं अगर वे निर्धारित कर रहे हैं।
मॉर्गन हेरलॉकर

1
@ साइमन- भी, केवल उन तरीकों को उजागर करना जो उपयोग करने के लिए सुरक्षित हैं, संभावित हुड को बढ़ाता है कि उपयोगकर्ता वर्ग का उपयोग करने की कोशिश करते समय कुछ नहीं तोड़ देगा। वहाँ आसानी से तरीके हैं जो एक वेबसर्वर को क्रैश कर सकते हैं यदि एक हजार बार कहा जाता है। आप नहीं चाहते हैं कि एपीआई के उपभोक्ता आपके लिए सक्षम हों। अमूर्तता सिर्फ एक सम्मेलन से अधिक है।
मॉर्गन हेरलॉकर

4

मेरा सुझाव है कि पृष्ठभूमि के लिए, आप वर्ग के आक्रमणकारियों के बारे में पढ़कर शुरू करते हैं ।

एक अपरिवर्तनीय, एक लंबी कहानी को छोटा करने के लिए, एक वर्ग की स्थिति के बारे में एक धारणा है जो एक वर्ग के जीवनकाल के दौरान सच माना जाता है।

आइए वास्तव में सरल C # उदाहरण का उपयोग करें:

public class EmailAlert
{
    private readonly List<string> addresses = new List<string>();

    public void AddRecipient(string address)
    {
        if (!string.IsNullOrEmpty(address))
            addresses.Add(address);
    }

    public void Send(string message)
    {
        foreach (string address in addresses)
            SendTo(address, message);
    }

    // Details of SendTo not shown
}

यहाँ क्या चल रहा है?

  • सदस्य addressesवर्ग निर्माण पर आरम्भिक है।
  • यह निजी है, इसलिए बाहर से कुछ भी इसे छू नहीं सकता है।
  • हमने इसे बनाया भी है readonly, इसलिए निर्माण के बाद इसे अंदर से कुछ भी नहीं छू सकता है (यह हमेशा सही / आवश्यक नहीं है, लेकिन यहां उपयोगी है)।
  • इसलिए, Sendविधि एक धारणा बना सकती है जो addressesकभी नहीं होने वाली है null। इसे उस जाँच को करने की ज़रूरत नहीं है क्योंकि ऐसा कोई तरीका नहीं है जिससे मूल्य को बदला जा सके।

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

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

इन अन्य प्रश्नों के लिए:

क्या इसका इस्तेमाल किसी वर्ग के गुप्त राज्य पर हमला करने से सुरक्षित करने के लिए किया जा सकता है?

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

क्या प्रतिबिंब इस तंत्र को ओवरराइड कर सकता है?

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

जानकारी को छिपाने के लिए कंपाइलर के लिए क्या सार्थक होगा?

संकलक पहले से ही इसे लागू करता है। तो क्या .NET, जावा, और अन्य ऐसे वातावरणों में रनटाइम करता है - विधि को कॉल करने के लिए उपयोग किया गया ओपकोड सफल नहीं होगा यदि विधि निजी है। उस प्रतिबंध के चारों ओर एकमात्र तरीका विश्वसनीय / उन्नत कोड की आवश्यकता है, और उन्नत कोड हमेशा प्रोग्राम की मेमोरी में सीधे लिख सकता है। यह कस्टम ऑपरेटिंग सिस्टम की आवश्यकता के बिना इसे लागू किया जा सकता है।


1
@ साइमन: हमें यहां "अज्ञानता" को स्पष्ट करने की आवश्यकता है। _अनुबंध के साथ एक विधि को उपसर्ग करना , लेकिन इसे लागू नहीं करता है। इससे अनुबंध से अनभिज्ञ होना कठिन हो सकता है , लेकिन यह अनुबंध को तोड़ने के लिए कठिन नहीं बनाता है , खासकर जब थकाऊ और अक्सर प्रतिबंधात्मक तरीकों जैसे प्रतिक्षेप के साथ तुलना नहीं की जाती है। एक अधिवेशन कहता है, "आपको यह नहीं तोड़ना चाहिए "। एक एक्सेस संशोधक कहता है, "आप इसे तोड़ नहीं सकते "। मैं यह कहने की कोशिश नहीं कर रहा हूं कि एक दृष्टिकोण दूसरे की तुलना में बेहतर है - वे दोनों आपके दर्शन के आधार पर ठीक हैं, लेकिन फिर भी वे बहुत अलग दृष्टिकोण हैं।
हारून पकड़ा गया

2
कैसे एक सादृश्य के बारे में: ए private/ protectedएक्सेस संशोधक एक कंडोम की तरह है। आपको एक का उपयोग करने की आवश्यकता नहीं है, लेकिन यदि आप नहीं जा रहे हैं, तो आप अपने समय और अपने साथी के बारे में निश्चित रूप से बेहतर होंगे। यह एक दुर्भावनापूर्ण कृत्य को नहीं रोकेगा, और हर बार काम भी नहीं कर सकता है, लेकिन यह निश्चित रूप से लापरवाही से जोखिम को कम करेगा, और "कृपया सावधान रहें" कहने की तुलना में कहीं अधिक प्रभावी ढंग से करें। ओह, और यदि आपके पास एक है, लेकिन इसका उपयोग न करें, तो मुझसे किसी भी सहानुभूति की उम्मीद न करें।
एरॉन

3

जानकारी छिपाना सिर्फ एक सम्मेलन से कहीं अधिक है; इसके चारों ओर जाने की कोशिश वास्तव में कई मामलों में कक्षा की कार्यक्षमता को तोड़ सकती है। उदाहरण के लिए, किसी privateचर में किसी मूल्य को संग्रहीत करना , उसी समय की संपत्ति protectedया publicसंपत्ति का उपयोग करके उसे उजागर करना बहुत आम बात है , और पाने वाले में, अशक्त की जाँच करें और कोई भी आरम्भिक कार्य करें जो आवश्यक हो (यानी, आलसी लोडिंग)। या एक privateचर में कुछ स्टोर करें , एक संपत्ति का उपयोग करके इसे उजागर करें, और सेटर में, यह देखने के लिए जांचें कि क्या मूल्य बदल गया और आग PropertyChanging/ PropertyChangedघटना। लेकिन आंतरिक कार्यान्वयन को देखे बिना, आप कभी नहीं जान पाएंगे कि यह सब पर्दे के पीछे चल रहा है।


3

जानकारी एक शीर्ष-डाउन डिज़ाइन दर्शन से विकसित हुई। पायथन को बॉटम-अप भाषा कहा गया है

जानकारी छिपाना जावा, सी ++ और सी # में कक्षा स्तर पर अच्छी तरह से लागू किया जाता है, इसलिए यह वास्तव में इस स्तर पर एक सम्मेलन नहीं है। सार्वजनिक इंटरफेस और छिपे (निजी) विवरण के साथ एक वर्ग को "ब्लैक बॉक्स" बनाना बहुत आसान है।

जैसा कि आपने बताया, पायथन में यह प्रोग्रामर के ऊपर है कि जो कुछ भी दिखाई दे रहा है, उसका उपयोग करने के इरादे से छिपा हुआ नहीं है।

यहां तक ​​कि जावा, सी ++ या सी # के साथ, कुछ बिंदु पर जानकारी छिपाना एक सम्मेलन बन जाता है। अधिक जटिल सॉफ्टवेयर आर्किटेक्चर में शामिल अमूर्त के उच्चतम स्तर पर कोई पहुंच नियंत्रण नहीं हैं। उदाहरण के लिए, जावा में आप ".internal" का उपयोग पा सकते हैं पैकेज के नाम। यह विशुद्ध रूप से एक नामकरण सम्मेलन है क्योंकि इस तरह की जानकारी को केवल पैकेज एक्सेसिबिलिटी के माध्यम से लागू किया जाना आसान नहीं है।

औपचारिक रूप से पहुंच को परिभाषित करने का प्रयास करने वाली एक भाषा एफिल है। यह लेख जावा जैसी भाषाओं की कुछ अन्य जानकारी को छिपाने वाली कमजोरियों को इंगित करता है।

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

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


1
+1 "सूचना के प्रोग्रामर के उपयोग" के उद्धरण के लिए, यह ठीक है (हालांकि आपके पास अंत में एक अतिरिक्त अल्पविराम है)।
2

2

रूबी और पीएचपी के पास यह है और इसे रनटाइम पर लागू करता है।

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

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

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


1
यदि आपकी लाइब्रेरी का उपयोग उसी कंपनी में किया जा रहा है जिसमें आप काम कर रहे हैं तो आप उसकी देखभाल करेंगे ... यदि वह अपने ऐप को क्रैश कर देता है, तो आपको इसे ठीक करने में कठिन समय होगा।
वुल्मो

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

1
@Simon: सामान के साथ एक इंटरफ़ेस अव्यवस्था क्यों आप लोगों का उपयोग नहीं करना चाहते हैं। मुझे नफरत है कि सी ++ को हेडर फ़ाइल में कक्षा की परिभाषा में मौजूद हर सदस्य की आवश्यकता है (मुझे समझ में आता है)। इंटरफेस अन्य लोगों के लिए हैं और उन चीजों से अटे नहीं होना चाहिए जिनका वे उपयोग नहीं कर सकते हैं।
फकहलर

1
@phkahler: इंटरफ़ेस से pydocनिकालता _prefixedMembersहै। संकलक द्वारा जांचे गए कीवर्ड की पसंद से क्लॉट किए गए इंटरफेस का कोई लेना-देना नहीं है।
14

2

Acces संशोधक निश्चित रूप से कुछ कर सकते हैं जो सम्मेलन नहीं कर सकता।

उदाहरण के लिए, जावा में आप निजी सदस्य / क्षेत्र का उपयोग नहीं कर सकते जब तक कि आप प्रतिबिंब का उपयोग न करें।

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

बेशक कुछ सुरक्षा कीड़े हो सकते हैं जो उसे इस पर काबू पाने की अनुमति देंगे, लेकिन यह दार्शनिक रूप से महत्वपूर्ण नहीं है (लेकिन व्यवहार में यह निश्चित रूप से है)।

यदि उपयोगकर्ता अपने वातावरण में मेरा इंटरफ़ेस चलाता है, तो उसके पास नियंत्रण है और इस तरह एक्सेस मॉडिफायर को दरकिनार कर सकता है।


2

मैं ऐसी स्थिति में नहीं था जहाँ इन खोजशब्दों के कारण संकलक त्रुटि ने मुझे बग से बचाया हो।

यह इतना के रूप में आवेदन लेखकों को बग से बचाने के लिए इतना नहीं है कि पुस्तकालय लेखकों को यह तय करने दें कि वे अपने कार्यान्वयन के किन हिस्सों को बनाए रखने के लिए प्रतिबद्ध हैं।

अगर मेरे पास एक पुस्तकालय है

class C {
  public void foo() { ... }

  private void fooHelper() { /* lots of complex code */ }
}

मैं fooकार्यान्वयन को बदलने में सक्षम होना चाहता हूं और संभवतः fooHelperकट्टरपंथी तरीकों से बदल सकता हूं । यदि लोगों के एक समूह ने उपयोग करने का निर्णय लिया हैfooHelper मेरे दस्तावेज़ में सभी चेतावनियों के बावजूद तो मैं ऐसा करने में सक्षम नहीं हो सकता।

privateलाइब्रेरी लेखकों को पुस्तकालयों को प्रबंधनीय आकार के तरीकों (और privateसहायक वर्गों) में इस डर के बिना तोड़ दिया जाता है कि वे वर्षों तक उन आंतरिक विवरणों को बनाए रखने के लिए मजबूर होंगे।


जानकारी को छिपाने के लिए कंपाइलर के लिए क्या सार्थक होगा?

एक तरफ ध्यान दें, जावा privateमें कंपाइलर द्वारा लागू नहीं किया गया है, लेकिन जावा बाइटकोड वेरिफायर द्वारा


क्या प्रतिबिंब इस तंत्र को ओवरराइड कर सकता है? जानकारी को छिपाने के लिए कंपाइलर के लिए क्या सार्थक होगा?

जावा में, न केवल प्रतिबिंब इस तंत्र को ओवरराइड कर सकता है। privateजावा में दो प्रकार हैं । उस तरह का privateएक बाहरी वर्ग दूसरे बाहरी वर्ग के privateसदस्यों तक पहुँचने से रोकता है जिसे बायटेकोड वेरिफ़ायर द्वारा चेक किया जाता है, बल्कि privateएक आंतरिक वर्ग द्वारा पैकेज-निजी सिंथेटिक एक्सेसर विधि के माध्यम से उपयोग किया जाता है

 public class C {
   private int i = 42;

   public class B {
     public void incr() { ++i; }
   }
 }

चूंकि क्लास B(वास्तव में नामित C$B) का उपयोग करता है i, संकलक एक सिंथेटिक एक्सेसर विधि बनाता है जो एक तरह Bसे उपयोग करने की अनुमति देता है C.iजो कि बायोटेक वेरिफायर से अतीत हो जाता है। दुर्भाग्य से, चूंकि ClassLoaderआप एक से एक वर्ग बनाने के लिए अनुमति देता है byte[], यह निजी तौर पर प्राप्त करने के लिए काफी सरल है जो Cआंतरिक वर्गों के लिए एक नए वर्ग के Cपैकेज में बनाकर प्रकट होता है जो संभव है यदिC जार को सील नहीं किया गया है।

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


क्या इसका इस्तेमाल किसी वर्ग के गुप्त राज्य पर हमला करने से सुरक्षित करने के लिए किया जा सकता है?

हाँ। "सुरक्षित अपघटन" तब संभव है जब प्रोग्रामर अपने मॉड्यूल की सुरक्षा गुणों को संरक्षित करते हुए सहयोग कर सकते हैं - मुझे अपने मॉड्यूल के सुरक्षा गुणों का उल्लंघन न करने के लिए किसी अन्य कोड मॉड्यूल के लेखक पर भरोसा नहीं करना है।

ऑब्जेक्ट क्षमता भाषा जैसे जो-ई सूचना छिपाने का उपयोग करती है और सुरक्षित अपघटन को संभव बनाने के लिए अन्य साधन:

जो-ई, जावा प्रोग्रामिंग लैंग्वेज का एक सबसेट है जिसे ऑब्जेक्ट-कैपेसिटी अनुशासन के अनुसार सुरक्षित प्रोग्रामिंग को सपोर्ट करने के लिए डिज़ाइन किया गया है। जो-ई का उद्देश्य सुरक्षित प्रणालियों के निर्माण की सुविधा के साथ-साथ जो-ई में निर्मित प्रणालियों की सुरक्षा समीक्षा की सुविधा प्रदान करना है।

उस पृष्ठ से जुड़ा पेपर इस बात का उदाहरण देता है कि privateप्रवर्तन कैसे सुरक्षित अपघटन को संभव बनाता है।

सुरक्षित इनकैप्सुलेशन प्रदान करना।

चित्रा 1. एक परिशिष्ट केवल लॉगिंग सुविधा।

public final class Log {
  private final StringBuilder content;
  public Log() {
    content = new StringBuilder();
  }
  public void write(String s) {
    content.append(s);
  }
}

अंजीर पर विचार करें। 1, जो बताता है कि कोई व्यक्ति केवल अपग्रेड लॉग सुविधा कैसे बना सकता है। बशर्ते कि बाकी कार्यक्रम जो-ई में लिखा गया है, एक कोड समीक्षक को that सेंध लगाई जा सकती है कि लॉग एंट्रीज को केवल जोड़ा जा सकता है, और मोडी or एड या हटाया नहीं जा सकता है। यह समीक्षा व्यावहारिक है क्योंकि इसमें केवल Log कक्षा के निरीक्षण की आवश्यकता होती है, और किसी अन्य कोड की समीक्षा की आवश्यकता नहीं होती है। नतीजतन, इस संपत्ति को सत्यापित करने के लिए लॉगिंग कोड के बारे में केवल स्थानीय तर्क की आवश्यकता होती है।


1

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


1

सुरक्षा को भाषा का हिस्सा बनाकर आप कुछ हासिल करते हैं: उचित आश्वासन।

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

अब सिंटैक्टिक प्रोटेक्शन प्राप्त करने के तरीके हैं? पूर्ण रूप से; अधिकांश भाषाएं उनके पास हैं। C ++ में, आप हमेशा क्लास को किसी अन्य प्रकार में डाल सकते हैं और इसके बिट्स पर प्रहार कर सकते हैं। जावा और सी # में, आप इसमें खुद को प्रतिबिंबित कर सकते हैं। इत्यादि।

हालाँकि, ऐसा करना कठिन है । यह स्पष्ट है कि आप कुछ ऐसा कर रहे हैं जो आपको नहीं करना चाहिए। आप इसे दुर्घटना से नहीं कर सकते (C ++ में जंगली लिखते हैं)। आपको स्वेच्छा से सोचना चाहिए, "मैं कुछ ऐसा छूने जा रहा हूं जो मुझे मेरे कंपाइलर द्वारा नहीं बताया गया था।" आपको स्वेच्छा से कुछ अनुचित करना चाहिए

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

सिंटैक्टिक सुरक्षा के बिना, गलत लोग गलत हैं: वर्ग का उपयोग करने वाले कई लोग। उन्हें अधिवेशन का पालन करना चाहिए या अनिर्दिष्ट बदबू आएगी। स्क्रैच कि: अनिर्दिष्ट बदबू आ सकती है है।

एपीआई से बदतर कुछ भी नहीं है, अगर आप गलत काम करते हैं, तो सब कुछ वैसे भी काम कर सकता है। यह उपयोगकर्ता को गलत आश्वासन देता है कि उन्होंने सही काम किया है, कि सब कुछ ठीक है, आदि।

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

वह सोचता है कि सम्मेलन मूर्खतापूर्ण है। और वह फिर कभी इसका पालन नहीं करेगा। और वह अपने सभी दोस्तों को भी परेशान नहीं करने के लिए कहेगा।

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