ऑब्जेक्ट ओरिएंटेड नुकसान से बचना, सी से पलायन, आपके लिए क्या काम किया?


12

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

मेरे पास ओओपी में एक विश्वविद्यालय पाठ्यक्रम है, और एनकैप्सुलेशन, डेटा अमूर्त, बहुरूपता, प्रतिरूपकता और विरासत के मूल सिद्धांतों को समझते हैं।

मैंने पढ़ा /programming/2688910/learning-to-think-in-the-object-oriented-way और /programming/1157847/learning-object-oriented-thinking , और उन उत्तरों में बताई गई कुछ पुस्तकों को देख रहे होंगे।

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

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

मैं कुछ की तर्ज पर सोच रहा हूं जैसे "क्या पर्यवेक्षक और संशोधक विधियों की उचित संख्या होना और निजी चर का उपयोग करना आम है या क्या उन्हें समेकित / कम करने की तकनीकें हैं?"

मैं सी + + का उपयोग शुद्ध ओओ भाषा के रूप में करने के बारे में चिंतित नहीं हूं, अगर तरीकों को मिश्रित करने के अच्छे कारण हैं। (GOTO का उपयोग करने के कारणों की याद दिलाते हुए, यद्यपि।

धन्यवाद!


2
एक पूर्ण उत्तर के योग्य नहीं है, लेकिन एक महत्वपूर्ण जिसने मुझे स्वीकार करने के लिए एक लंबा समय लिया (यानी मैंने इसके बारे में बहुत बार पढ़ा लेकिन इसे फैनबॉय टॉक के रूप में माना जाता है): सदस्य कार्यों पर मुफ्त funtcions पसंद करते हैं। यह आपकी कक्षाओं को न्यूनतम रखता है जो एक अच्छी बात है।
६:४१

@stijn अनिवार्य रूप से आप कह रहे हैं कि अगर इसे कक्षा में रहने की आवश्यकता नहीं है, तो इसे वहां न डालें। उदाहरण के लिए मुझे बहुत सारे यूटिलिटी मेंबर फ़ंक्शंस दिखाई देते हैं जो आसानी से कोड में फ्री फ़ंक्शंस हो सकते हैं जो मैंने अब तक पढ़े हैं।
स्टीफन

हाँ बस यही। यदि आप 'गैर-सदस्यीय गैर-मित्र को प्राथमिकता देते हैं' की खोज करते हैं, तो आपको इसके बारे में बहुत सारी जानकारी मिल जाएगी। अंत में यह सिंगल
रिस्पांसिबिलिटी

जवाबों:


10

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


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

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

9

अच्छी तरह से पहला बहुत अधिक जानकारी को उजागर करने का नुकसान है। डिफ़ॉल्ट होना चाहिए private, नहीं public

उसके बाद बहुत सारे गेटर्स / सेटर आते हैं। मान लीजिए कि मेरे पास एक डेटा सदस्य है। क्या मुझे वास्तव में अन्य वर्ग में इस डेटा की आवश्यकता है? ठीक है, एक गटर बनाओ। क्या मुझे वास्तव में वस्तु के जीवनकाल के दौरान इस डेटा को बदलने की आवश्यकता है? फिर एक सेटर बनाओ।

अधिकांश नौसिखिए प्रोग्रामर के पास प्रत्येक डेटा सदस्य के लिए एक गेट्टर / सेटर बनाने के लिए डिफ़ॉल्ट होता है। यह क्लैटर इंटरफेस और अक्सर खराब डिजाइन विकल्प होते हैं।


2
हां, यह उन लोगों में काफी लोकप्रिय है, जो डेटा को निजी बनाने के लिए अल्पज्ञता को समझते हैं और फिर गेटर्स और सेटर्स के साथ एनकैप्सुलेशन को उड़ा देते हैं।
जीन बुशुइव

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

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

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

2

जब मैंने उस चैस को पार किया तो मैं निम्नलिखित दृष्टिकोण पर आ गया:

0) मैंने छोटे / मध्यम आकार के प्रक्रियात्मक ऐप और काम पर कोई मिशन-महत्वपूर्ण सामान के साथ धीमी शुरुआत की।

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

2) फिर अगला चरण व्युत्पन्न बनाया गया।

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

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


2

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


हाँ! इससे पहले कि कोई व्यक्ति किसी चीज़ का स्वामी बन जाए, वह अपने सामने काम करने वाले महान गुरुओं की नकल करना सीख जाता है। लागू किए गए अच्छे कोड का अध्ययन करना सीखने का एक अच्छा तरीका है। मैं सरल डिजाइनों से शुरू होने और किसी की समझ में सुधार के रूप में गहराई से देखने को बढ़ावा देने की सलाह दूंगा।
जीन बुशुइव

1

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

एक चीज जो आप निश्चित रूप से नहीं करना चाहते हैं वह एक फ़ील्ड है जिसे म्यूटेटर में स्थिरता के लिए जाँच की जानी चाहिए, और इसे सार्वजनिक छोड़ दें।


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

1
हाँ, मैं यहाँ सहमत हूँ यदि आप C ++ में हैं (जो प्रश्न का उल्लेख किया था), लेकिन मैं अपना अधिकांश काम जावा में करता हूं, और हमारे पास कोई संरचना नहीं है, दुर्भाग्य से।

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

1

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


1

मैं सी + + का उपयोग शुद्ध ओओ भाषा के रूप में करने के बारे में चिंतित नहीं हूं, अगर तरीकों को मिश्रित करने के अच्छे कारण हैं। (GOTO का उपयोग करने के कारणों की याद दिलाते हुए, यद्यपि।

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

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

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

टेम्पलेट्स की मेटाप्रोग्रामिंग क्षमता भी काफी प्रभावशाली है। उदाहरण के लिए Boost.Units लाइब्रेरी देखें। यह पुस्तकालय आयामी मात्रा के लिए प्रकार का समर्थन प्रदान करता है। मैंने वर्तमान में जिस इंजीनियरिंग फर्म के लिए काम किया है, उसमें इस लाइब्रेरी का व्यापक उपयोग किया है। यह सिर्फ संभावित प्रोग्रामर के एक पहलू, या यहां तक ​​कि विनिर्देश त्रुटि के लिए बहुत अधिक तत्काल प्रतिक्रिया प्रदान करता है। यह एक प्रोग्राम को संकलित करना असंभव है जो एक सूत्र का उपयोग करता है जहां '=' ​​ऑपरेटर के दोनों पक्ष स्पष्ट रूप से कास्टिंग के बिना dimensionally समकक्ष नहीं हैं। मुझे व्यक्तिगत रूप से किसी भी अन्य भाषा के साथ कोई अनुभव नहीं है जिसमें यह संभव है, और निश्चित रूप से एक के साथ नहीं है जिसमें सी ++ की शक्ति और गति भी है।

मेटाप्रोग्रामिंग एक विशुद्ध रूप से कार्यात्मक प्रतिमान है।

तो वास्तव में, मुझे लगता है कि आप पहले से ही कुछ दुर्भाग्यपूर्ण गलतफहमी के साथ सी ++ में कदम रख रहे हैं। OO के अलावा अन्य प्रतिमानों को टाला नहीं जाना है, उन्हें LEVERAGED किया जाना है। उस प्रतिमान का उपयोग करें जो आपके द्वारा काम की जा रही समस्या के पहलू के लिए स्वाभाविक है। जो वस्तु अनिवार्य रूप से एक वस्तु प्रवण समस्या नहीं है उस पर बल न डालें। जहां तक ​​मेरा सवाल है, OO C ++ के लिए आधी कहानी भी नहीं है।


क्या वर्चुअल कीवर्ड C ++ में वर्चुअल क्लास की कार्यक्षमता प्रदान नहीं करता है? जहां तक ​​गोटो की टिप्पणी है, जो मैं चला रहा था वह यह था कि मैं अनुभवजन्य नियमों को तोड़ने के बारे में चिंतित नहीं हूं, जब तक कि मैं तर्क को समझता हूं। हालांकि, मैं OO के पक्ष में चौंकाने वाली अनिवार्य / प्रक्रियात्मक की ओर देख रहा हूं, जो आवश्यक हो सकता है। धन्यवाद।
स्टीफन

आभासी तरीके बहुरूपता के लिए एक शर्त नहीं है, यह इसे करने का एक सामान्य तरीका है। वास्तव में, बाकी सब कुछ समान है, तो एक विधि को आभासी बनाने से वास्तव में इनकैप्सुलेशन कमजोर हो जाता है, क्योंकि आप वर्ग 'एफ़ी' के आकार को बढ़ा रहे हैं, और आप यह सुनिश्चित करना कठिन बनाते हैं कि आप लिस्कॉव और इसी तरह का पालन करें। कुछ तभी वर्चुअल करें जब आपको सीम की आवश्यकता हो, वंशानुक्रम के माध्यम से नए व्यवहार को इंजेक्ट करने के लिए कुछ जगह (हालांकि विरासत भी OOP में सतर्क रहने के लिए कुछ है)। वर्चुअल के लिए वर्चुअल एक वर्ग को "अधिक ओओपी" नहीं बनाता है
सारा

1

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

@nightcracker

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

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

डोमिनिक गुरटो

इससे पहले कि आप कार्यान्वयन के बारे में सोचना शुरू करें, इंटरफ़ेस डिज़ाइन करें। जीन बुशुयेव इंटरफ़ेस डिजाइन और कार्यान्वयन अक्सर अंतिम पुनरावृत्ति होने तक लगातार पुनरावृत्तियों में हाथ से चलते हैं।

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

wantTheBest

मैंने छोटे / मध्यम आकार के प्रक्रियात्मक ऐप और काम पर कोई मिशन-महत्वपूर्ण सामान के साथ धीमी शुरुआत की। मूल प्रक्रियात्मक कोड में, डेटा संरचनाओं को प्रेक्षक / संशोधक कोड से अलग करें

यह बहुत समझ में आता है ... मुझे काम पर काम करने का विचार रखना पसंद था, लेकिन कक्षाओं के साथ कुछ गैर-महत्वपूर्ण सामान को फिर से बनाने के लिए।

jpm

एक चीज जो आप निश्चित रूप से नहीं करना चाहते हैं वह एक फ़ील्ड है जिसे म्यूटेटर में स्थिरता के लिए जाँच की जानी चाहिए, और इसे सार्वजनिक छोड़ दें

मैं थोड़ी देर के लिए जाना जाता हूं कि यह डेटा एनकैप्सुलेट करने की ताकत में से एक है ... स्थिरता को लागू करने और उस मामले की स्थितियों / सीमाओं / आदि के लिए सक्षम होने के नाते।

क्रेजी एडी

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

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

तो फिर, सभी को धन्यवाद जिन्होंने जवाब दिया!


0

सबसे बड़ा नुकसान यह है कि ओओपी एक चांदी की गोली है, या "एक आदर्श प्रतिमान" है।

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