हमें निजी चर की आवश्यकता क्यों है?


210

हमें कक्षाओं में निजी चर की आवश्यकता क्यों है?

मैंने पढ़ा है प्रोग्रामिंग पर हर किताब कहती है कि यह एक निजी चर है, यह है कि आप इसे कैसे परिभाषित करते हैं लेकिन वहां रुक जाता है।

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

  1. निजी चर क्या रोकने में मदद करते हैं?

  2. आप कैसे तय करते हैं कि कोई विशेष संपत्ति निजी होनी चाहिए या नहीं? यदि हर क्षेत्र में डिफ़ॉल्ट रूप से निजी होना चाहिए तो एक वर्ग में सार्वजनिक डेटा सदस्य क्यों हैं?

  3. किन परिस्थितियों में एक चर को सार्वजनिक किया जाना चाहिए?


9
आपका प्रश्न बहुत भाषा-अज्ञेय लगता है, लेकिन आपने इसे जावा और c ++ के रूप में टैग किया है। यदि आप उन दो भाषाओं के बाहर के दृष्टिकोणों में रुचि रखते हैं, तो आपको शायद ऐसा कहना चाहिए।
जेम्स

8
रिकॉर्ड के लिए, एक निजी विधि बनाने से "सुरक्षा" नहीं बढ़ती है। आपके एप्लिकेशन के अन्य भाग अभी भी प्रतिबिंब का उपयोग करके निजी सदस्यों तक पहुंच सकते हैं।
14

3
निजी और सार्वजनिक चर का उपयोग और अंतर, और हमारे पास क्यों है, उन्हें केवल सामान्य वस्तु-उन्मुख सिद्धांतों के संदर्भ में समझा जा सकता है। इसे अलग से नहीं समझा जा सकता है। आपको शायद इसे उस दृष्टिकोण से देखने की जरूरत है, चीजें स्पष्ट हो सकती हैं।
नज़र मेरजा


3
यदि आप अपनी कार में सीटबेल्ट का उपयोग करके किसी को भी पकड़ते हैं, तो आपको उनका ड्राइविंग लाइसेंस ले लेना चाहिए, क्योंकि जाहिर है कि वे ड्राइव करने की अपनी क्षमताओं पर भरोसा नहीं करते हैं।
gnasher729

जवाबों:


308

यह विश्वास का विषय नहीं है, बल्कि प्रबंधन की जटिलता का है।

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

एक निजी सदस्य, इसके विपरीत, केवल उसी वर्ग के अंदर से पहुँचा जा सकता है, इसलिए यदि कुछ गलत हो जाता है, तो आमतौर पर देखने के लिए केवल एक स्रोत फ़ाइल होती है। यदि आपके पास अपने प्रोजेक्ट में एक लाख लाइनों का कोड है, लेकिन आपकी कक्षाएं छोटी रखी जाती हैं, तो यह आपके बग ट्रैकिंग प्रयास को 1000 के कारक से कम कर सकता है।

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

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

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


24
+1 समस्या के दिल में उतरने के लिए, हालांकि मैंने व्यक्तिगत रूप से अपना कोड बनाए रखना आसान बना लिया है जब मैंने हुप्स से गुजरना बंद कर दिया है ताकि यह सुनिश्चित हो सके कि अक्सर इस्तेमाल किया जाने वाला चर निजी रहता है। निश्चित रूप से भविष्य में एक त्रुटि सामने आ सकती है, लेकिन यह कोड की 60 कम पंक्तियों के माध्यम से झारना है, और कम चर और बूट करने के लिए कार्य करता है;)
जेफरी स्वीनी

48
आधुनिक कंप्यूटिंग की पवित्र कब्र जटिलता को नीचे रख रही है।

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

2
ठीक है कि। जब लोग "सूचना छिपाना" सुनते हैं, तो वे सोचते हैं कि उन्हें एन्क्रिप्शन कुंजी, डेटाबेस क्रेडेंशियल्स, आदि जैसी चीजों के लिए निजी चर का उपयोग करना चाहिए
वेन वर्नर

2
@AdamZerner देखें "बताओ, मत पूछो" ( martinfowler.com/bliki/TellDontAsk.html ) पहली बार में गेटर्स / सेटर करने के बारे में - लेकिन अन्यथा हाँ, क्योंकि आपको कभी भी मूल्य के आंतरिक प्रतिनिधित्व को बदलने के लिए स्वतंत्र होना चाहिए तुम चाहो। हमेशा की तरह, कुछ अपवाद हैं ... (उदाहरण के लिए डीटीओ)
डबल यू

111

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

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

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


24
IMO यह लिबास लेखक और लिबास उपभोक्ता के बीच संचार के बारे में भी है। सार्वजनिक इंटरफ़ेस "इस का उपयोग करें" की तरह है और प्राइवेट जावा में "सिवाय इसके कि" का उपयोग नहीं करते हैं, आप वास्तव में इसे दुर्घटना से उपयोग नहीं कर सकते हैं अगर यह निजी है तो यह सुरक्षित और स्पष्ट है।
चक्री

5
@ सहचर और अन्य: ध्यान दें कि जो वास्तव में आपके निजी क्षेत्रों और विधियों का उपयोग करने के लिए बाहर हैं वे ऐसा कर सकते हैं (प्रतिबिंब के माध्यम से)। private"सुरक्षा के लिए मुख्य रूप से अभिप्रेत नहीं" से कम है, यह बोलने के लिए कोई "सुरक्षा" प्रदान नहीं करता है। यह सिर्फ एक मजबूत संकेत है (संकलक के माध्यम से वितरित) इसे एक्सेस नहीं करना।

@delnan ने मुहावरा ध्यान दिया "हां" शायद मैं उस पर अधिक स्पष्ट होऊं।
१०:१२ बजे चक्र

@ अचरित हां, मेरा मतलब यह नहीं था कि आप गलत थे। मैं बस उस बिंदु को बढ़ावा देना चाहता था।

1
@ डलेन: निजी क्षेत्र, कुछ भाषाओं में, सुरक्षा के कुछ निश्चित रूप प्रदान करते हैं। उदाहरण के लिए, एरिक लिपर्ट का उत्तर देखें कि क्या सी # में एक सुरक्षा उद्देश्य के लिए पहुँच स्तर और संशोधक (निजी, सील, आदि) सेवा करते हैं?
ब्रायन

25

यहाँ कीवर्ड एनकैप्सुलेशन है । OOP में आप अपनी वस्तुओं / वर्गों के उचित एनकैप्सुलेशन को लागू करने के लिए निजी चर का उपयोग करना चाहते हैं।

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

  1. इसलिए, निजी चर यह सुनिश्चित करते हैं कि संबंधित चर केवल परिभाषित कक्षा में ही रहे। यदि आपको इसे बदलने की आवश्यकता है, तो परिवर्तन स्थानीय स्तर पर ही होता है।

  2. C ++ या Java जैसे पारंपरिक लेनगेज में, आप आमतौर पर सब कुछ निजी और केवल इसी गेटर्स और सेटर द्वारा सुलभ बनाते हैं। वास्तव में बहुत कुछ तय करने की आवश्यकता नहीं है।

  3. कभी-कभी, एफ.एक्स। C ++ संरचना में, आपको कई चीजों को एक साथ समूह करने के लिए केवल एक वर्ग की आवश्यकता होती है। उदाहरण के लिए, एक वेक्टर वर्ग पर विचार करें जिसमें एक xऔर एक yविशेषता है। उन मामलों में, आप उन्हें सार्वजनिक घोषित करके इन विशेषताओं तक सीधी पहुँच की अनुमति दे सकते हैं। विशेष रूप से, आपको यह ध्यान नहीं रखना चाहिए कि बाहर का कोई कोड आपकी कक्षा के किसी ऑब्जेक्ट को सीधे नए मानों में लिखकर संशोधित करता है xया नहीं y

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

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

इससे यह भी पता चलता है कि अन्य क्षेत्रों को शामिल करने के लिए आपके ज्ञान को व्यापक बनाने से आप मौजूदा अवधारणाओं को पूरे नए तरीके से देख सकते हैं।


1
+1 "जबकि अन्य प्रोग्रामर आपको प्राप्त करने के लिए बाहर नहीं हैं, वे आपके कोड के साथ बातचीत करते हैं।" आपके कोड का उपयोग करने वाले प्रोग्रामर स्वाभाविक रूप से बुरे नहीं हैं। निजी चर का उपयोग करके आप यह सुनिश्चित करते हैं कि वे (और आप, भविष्य में) कोड का उपयोग करके चोट न करें। यह आपको एक बेहतर API डिज़ाइन करने और उसे दस्तावेज़ करने में भी मदद करता है।
szalski

7

निजी चर यह सुनिश्चित करते हैं कि किसी वस्तु या कार्य के दायरे से बाहर के संदर्भ बाद में अनजाने में अन्य चर को प्रभावित नहीं करेंगे। बड़ी प्रोग्रामिंग परियोजनाओं के लिए, यह बहुत सारी दिलचस्प समस्याओं से बचने में मदद कर सकता है (जो आमतौर पर कंपाइलर द्वारा पकड़े नहीं जाते हैं)।

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

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

यदि वह चर निजी था, तो वह बाहर से बदला नहीं जा सकेगा:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

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

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

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


यह स्पष्ट नहीं है कि 3 चेतावनी क्यों "उह ओह!" इस मामले में। शायद यही वह प्रोग्रामर होना चाहता था।
इमिबिज़

@ इमिबीस शायद, और शायद मुझे जवाब में अधिक विस्तृत होना चाहिए। लेकिन गुणों का उपयोग कुछ ओओपी सिद्धांतों का उल्लंघन करने के लिए दरवाजा खोल सकता है जैसे कि खुले-बंद सिद्धांत या एलओडी, जैसा कि आप संभावित रूप से कार्यान्वयन विवरणों को उजागर कर रहे हैं। 'अपनी बात पर यह निर्भर करता है कि संपत्ति क्या है। अधिकांश भाषाएं संदर्भ के रूप में वस्तुओं का उपयोग करती हैं, और जब वस्तुओं के संदर्भ चारों ओर से गुजरते हैं और साथी देवता चुपचाप गुणों को बदलते हैं, तो यह वास्तव में डीबग करना कठिन हो सकता है। IMO यह बहुत आसान है और अगर आप एक वर्ग उदाहरण है, तो तरीकों के साथ काम करने के लिए अधिक विस्तार योग्य है।
जेफरी स्वीनी

7

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

ऐसा नहीं है कि गोपनीयता के बिना भाषाएँ ऐसी डिज़ाइन को असंभव बनाती हैं, बस कम संभावना है। ऐसा कुछ लिखने के लिए प्रेरित किए जाने के बजाय foo.getBar(), लोगों को लगता है कि एक गेट्टर आवश्यक नहीं है, क्योंकि यह लिखना आसान है foo.bar, लेकिन तब यह निर्णय फिर से नहीं लिया जाता है जब आप बाद में लंबे समय तक मठों की तरह समाप्त हो जाते हैं obj.container[baz].foo.bar। प्रोग्रामर जिन्होंने कभी कठोर भाषा में काम नहीं किया है, वे यह भी नहीं देख सकते हैं कि इसमें क्या गलत है।

यही कारण है कि गोपनीयता के बिना भाषाओं में लोग अक्सर ऐसे नामकरण मानकों को अपनाएंगे जो इसे अनुकरण करते हैं, जैसे कि सभी "निजी" सदस्यों को अंडरस्कोर देना। जब भाषा इसे लागू नहीं करती तब भी यह एक उपयोगी संकेत है।


3

सभी चर निजी होने चाहिए जब तक कि उन्हें पूरी तरह से सार्वजनिक होने की आवश्यकता न हो (जो लगभग कभी नहीं हो, आपको संपत्तियों / गेटर्स और बसने वालों का उपयोग करना चाहिए)।

चर काफी हद तक वस्तु की स्थिति प्रदान करते हैं, और निजी चर दूसरों को वस्तु की स्थिति में जाने और बदलने से रोकते हैं।


5
एक तरह से विषय वस्तु का बहुत संकीर्ण दृष्टिकोण। ऐसे मामले हैं जहां सार्वजनिक क्षेत्र की पहुंच को वारंट किया जाता है, यहां तक ​​कि पसंद किया जाता है
रोलाण्ड टीपीपी

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

1
@ दाविद शायद बीब का कहने का मतलब यह है कि "निजी चर दूसरों को अंदर जाने से रोकते हैं और अंधाधुंध वस्तु की स्थिति को बदलते हैं।" सार्वजनिक तरीके वस्तु की निजी स्थिति को बदल सकते हैं, लेकिन केवल उन तरीकों से जो वस्तु के कामकाज के लिए आवश्यक और सुसंगत हैं।
मैक्स नानसी

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

2
  • निजी चर क्या रोकने में मदद करते हैं?

यह स्पष्ट करने के बारे में है कि कौन से गुण और विधियां इंटरफ़ेस हैं और कौन से वास्तव में कोर कार्यक्षमता हैं। सार्वजनिक तरीके / गुण अन्य कोड के बारे में हैं अक्सर आपकी वस्तुओं का उपयोग करते हुए अन्य डेवलपर कोड। मैंने कभी भी एक ही प्रोजेक्ट पर 100+ की टीमों पर काम नहीं किया है, लेकिन मेरे अनुभव में 3-5 के साथ 20 से 20 अन्य डेवलपर्स के साथ जो मैंने लिखा है, सामान का उपयोग करते हुए अन्य चिंताएं मूर्खतापूर्ण लगती हैं।

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

  • आप यह कैसे तय करते हैं कि संपत्तियों का एक विशेष सेट निजी होना चाहिए या नहीं? यदि हर क्षेत्र में डिफ़ॉल्ट रूप से निजी होना चाहिए तो एक वर्ग में सार्वजनिक डेटा सदस्य क्यों हैं?

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

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

  • किन परिस्थितियों में एक चर को सार्वजनिक किया जाना चाहिए?

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


IMHO, सार्वजनिक वर्ग होने के साथ विशेष रूप से कुछ भी गलत नहीं है जिसका एकमात्र उद्देश्य सार्वजनिक चर को उजागर करना है। दरअसल, JVM उस उद्देश्य के लिए निर्मित वर्गों की एक संख्या है: int[], double[], Object[], आदि एक होना चाहिए, हालांकि, कैसे एक को उजागर करता है इस तरह के एक वर्ग के उदाहरण के बारे में बहुत सावधान रहना होगा। का अर्थ void CopyLocationTo(Point p);[एक को स्वीकार Pointफोन करने वाले से] से स्पष्ट है Point location(), क्योंकि यह स्पष्ट नहीं है कि क्या प्रभाव Point pt = foo.location(); pt.x ++;के स्थान पर होगा foo
सुपरकैट

2

SO पर संबंधित प्रश्न के लिए मेरा यह पोस्ट देखें ।

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

इस प्रकार उचित सदस्य स्कूपिंग स्व-दस्तावेजीकरण कोड में महत्वपूर्ण है।


2

मैं वास्तविक उदाहरण का उपयोग करके एक अलग दृष्टिकोण से एनकैप्सुलेशन के मूल्य के बारे में बात करने जा रहा हूं। कुछ समय पहले (80 के दशक की शुरुआत में) एक गेम रेडियो शेक कलर कंप्यूटर के लिए लिखा गया था जिसे डग्गेनॉन ऑफ़ डगोरथ कहा जाता है। कुछ साल पहले, रिचर्ड हुनरलच ने इसे एक पेपर असेंबलर लिस्टिंग से C / C ++ ( http://mspencer.net/daggorath/dodpcp.html ) पर पोर्ट किया । कुछ समय बाद, मुझे कोड मिला और बेहतर एनकैप्सुलेशन, ( http://dbp-consulting.com/stuff/ ) देने के लिए इसे री-फैक्टर करने लगा ।

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

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

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

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


"हमारे कार्यकारी उपयोगकर्ताओं की स्वतंत्रता" और "हमारे लिए कम परेशानी" के बीच का कठिन संतुलन। मैं यह मानना ​​शुरू कर रहा हूं कि एनकैप्सुलेशन इस मायने में बेहतर है कि मैं अपने कोडिंग पर बग को रोकूंगा, और मैं अंत उपयोगकर्ताओं को बग को रोकने में मदद करूंगा। लेकिन स्वतंत्रता की कमी बस उन्हें दूर कर सकती है, विकल्प की तलाश में ... कोडिंग अभी तक उपयोग नहीं की जा सकती है लेकिन सार्वजनिक तरीकों के माध्यम से पूर्वाभास कार्यात्मकता को संतुलित करने में मदद कर सकते हैं, लेकिन अधिक समय की मांग करते हैं।
कुंभ राशि

बहुत बुरा माना गया संस्करण
गिथूब

2

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

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

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


1

OOP अवधारणा में विरासत में इसकी एक विशेषता है (जावा या C ++)। इसलिए यदि हम विरासत में जा रहे हैं (इसका अर्थ है कि हम विरासत वाले वर्ग के चर का उपयोग करने जा रहे हैं), तो उन चर को प्रभावित करने की संभावना है। इसलिए हमें यह तय करना होगा कि चर बदले जा सकते हैं या नहीं।

केवल इस उद्देश्य के लिए, हम OOP में एक्सेस मॉडिफायर का उपयोग कर रहे हैं। मॉडिफायर में से एक निजी है जिसका अर्थ है कि इसे केवल उस वर्ग तक ही पहुँचा जा सकता है। कोई भी अन्य वर्ग उन चरों को प्रभावित नहीं कर सकता है।

जैसा कि हम जानते हैं, संरक्षित साधन का उपयोग उस वर्ग द्वारा किया जा सकता है जो विरासत में जा रहा है।

OOP में एक संशोधक अवधारणा क्यों है, इन कारणों के कारण है (कोई भी वर्ग OOP अवधारणा का उपयोग करके अन्य वर्ग चर का उपयोग कर सकता है)। यदि कोई संशोधक अवधारणा नहीं है, तो इसका मतलब है कि कक्षाओं को विरासत में लेना या अन्य ओओपी अवधारणाओं का उपयोग करना मुश्किल होगा।


1

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

लेकिन दूसरे हाथ में, जो दूसरों द्वारा अनदेखा किया गया है वह संरक्षित क्षेत्रों के बारे में है।

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

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

लेकिन दूसरी ओर, निजी क्षेत्र आपके कोड के लचीलेपन को अन्य उपयोगकर्ताओं के लिए कम करते हैं।

लचीलापन बनाम मुसीबतें, पेशेवरों और विपक्ष:

संरक्षित क्षेत्रों के साथ वेनिला वर्ग में आपके कोड द्वारा त्वरित वस्तुएं सुरक्षित हैं और आपकी एकमात्र जिम्मेदारी है।

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

इसलिए, संरक्षित क्षेत्रों / विधियों को अच्छी तरह से प्रलेखित नहीं किया गया है, या यदि उपयोगकर्ता वास्तव में यह नहीं समझते हैं कि ऐसे फ़ील्ड और विधियों का उपयोग कैसे किया जाना चाहिए, तो अपने आप को और आपके लिए अनावश्यक परेशानी पैदा करने का एक अच्छा मौका है।

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

इसलिए, निजी, संरक्षित और सार्वजनिक के बीच एक अच्छा संतुलन वही है जो वास्तव में मायने रखता है।

अब, निजी और संरक्षित के बीच निर्णय लेना वास्तविक समस्या है।

संरक्षित उपयोग कब करें?

हर बार जब आप समझते हैं कि एक क्षेत्र अत्यधिक लचीला हो सकता है, तो इसे संरक्षित रूप में कोडित किया जाना चाहिए। वह लचीलापन है: अशक्त होने से (जहाँ अशक्तता की हमेशा जाँच की जाती है और एक मान्य राज्य के रूप में मान्यता दी जाती है, अपवाद नहीं फेंकते), अपने वर्ग पूर्व द्वारा उपयोग किए जाने से पहले अड़चनें होना। > = 0, <100 आदि, और स्वचालित रूप से अधिक / कम-प्रवाहित मूल्यों के लिए तय किया गया, अधिकांश चेतावनी संदेश फेंक रहा है।

इसलिए, ऐसे संरक्षित क्षेत्र के लिए, आप एक गेट्टर बना सकते हैं और केवल इसका उपयोग कर सकते हैं (फ़ील्ड चर का उपयोग करने के बजाय), जबकि अन्य उपयोगकर्ता इसका उपयोग नहीं कर सकते हैं, यदि वे अपने विशिष्ट कोड के लिए अधिक लचीलापन चाहते हैं, तो मेरे उदाहरण में हो सकता है : अगर वे चाहते हैं कि नकारात्मक मूल्य उनके विस्तारित वर्ग पर ठीक काम करें।


-1

imo @tdammers सही नहीं है और वास्तव में भ्रामक है।

कार्यान्वयन विवरण छिपाने के लिए निजी चर मौजूद हैं। आपकी कक्षा स्कोर स्कोर करने के लिए Aएक arrayका उपयोग कर सकती है । कल आप एक treeया priority queueइसके बजाय का उपयोग करना चाह सकते हैं । आपकी कक्षा के सभी उपयोगकर्ताओं को स्कोर और नाम इनपुट करने addScore()का एक तरीका है और यह पता लगाने का एक तरीका है कि शीर्ष 10 कौन हैं getTop(n)

उन्हें अंतर्निहित डेटा संरचना तक पहुंचने की आवश्यकता नहीं है। बहुत अच्छा लगता है? खैर, कुछ कैवियट हैं।

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

आप जो सबसे अच्छा काम कर सकते हैं, वह यह है कि आपके कार्यक्रम में कितनी मात्रा में स्थिति है और जब संभव हो तो शुद्ध कार्यों का उपयोग करें।


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

1
इस कुछ भी पर्याप्त पेशकश करने के लिए अंक बनाया और में पहले 17 जवाब में विस्तार से बताया नहीं लगता है
कुटकी

-4

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

अमूर्तता - आपको तर्क के विचार को लागू करने की आवश्यकता के बिना पता होना चाहिए।

एनकैप्सुलेशन - आप ऑब्जेक्ट के अंडरलाइन कार्यान्वयन को नहीं देख सकते हैं। केवल आप ऑब्जेक्ट का सार्वजनिक इंटरफ़ेस देख सकते हैं।

अब C #, Java, C ++ जैसे ऑब्जेक्ट ओरिएंटेड प्रोग्राम में से किसी एक के साथ विशिष्ट कार्यान्वयन में आप इन अवधारणाओं को लागू कर सकते हैं।

निजी - कार्यान्वयन जो बाहरी दुनिया से छिपा होना चाहिए। ताकि आप उसे बदल सकें और आपकी कक्षा का उपयोगकर्ता प्रभावित न हो।

सार्वजनिक - यह वह इंटरफ़ेस है जिसके द्वारा कोई आपकी वस्तु का उपयोग कर सकता है।


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