CodeGym/Java Blog/अनियमित/भाग 7. एमवीसी (मॉडल-व्यू-कंट्रोलर) पैटर्न का परिचय
John Squirrels
स्तर 41
San Francisco

भाग 7. एमवीसी (मॉडल-व्यू-कंट्रोलर) पैटर्न का परिचय

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

एमवीसी का इतिहास

1970 के दशक के अंत में ज़ेरॉक्स PARC में काम करते समय MVC के पीछे के विचारों को ट्राईगवे रीन्सकॉग द्वारा तैयार किया गया था। उन दिनों, कंप्यूटर के साथ काम करने के लिए एक डिग्री और बड़े दस्तावेज़ों के निरंतर अध्ययन की आवश्यकता होती थी। Reenskaug द्वारा बहुत मजबूत डेवलपर्स के एक समूह के साथ हल किया गया कार्य कंप्यूटर के साथ एक सामान्य उपयोगकर्ता की सहभागिता को आसान बनाना था। ऐसे उपकरण बनाना आवश्यक था, जो एक ओर, अत्यंत सरल और समझने योग्य हों, और दूसरी ओर, कंप्यूटर और जटिल अनुप्रयोगों को नियंत्रित करना संभव बनाते। रीन्सकॉग ने एक टीम पर काम किया जिसने "सभी उम्र के बच्चों के लिए" एक लैपटॉप कंप्यूटर विकसित किया - डायनाबूक, साथ ही एलन के के नेतृत्व में स्मॉलटॉक भाषा। यही वह समय था जब एक दोस्ताना इंटरफेस की अवधारणा रखी गई थी। कई मामलों में, Reenskaug और उनकी टीम द्वारा किए गए कार्य ने IT क्षेत्र के विकास को प्रभावित किया। यहां एक दिलचस्प तथ्य है जो एमवीसी पर सीधे लागू नहीं होता है, लेकिन इन विकासों के महत्व को दर्शाता है। एलन केकहा, "जब मैं पहली बार Apple गया, जो '84 में था, मैक पहले से ही बाहर था और न्यूजवीक ने मुझसे संपर्क किया और मुझसे पूछा कि मैं मैक के बारे में क्या सोचता हूं। मैंने कहा, 'ठीक है, मैक पहला पर्सनल कंप्यूटर है जो काफी अच्छा है आलोचना की जाए।' इसलिए, 2007 में आईफोन की घोषणा करने के बाद, उन्होंने इसे मेरे पास लाया और मुझे सौंप दिया। उन्होंने कहा, 'एलन, क्या यह आलोचना के लिए पर्याप्त है?' और मैंने कहा, 'स्टीव, इसे टैबलेट जितना बड़ा बना दो और तुम दुनिया पर राज करोगे।'" 3 साल बाद, 27 जनवरी, 2010 को, Apple ने 9.7 इंच के विकर्ण के साथ iPad पेश किया। दूसरे शब्दों में, स्टीव जॉब्स ने लगभग पूरी तरह से एलन के की सलाह का पालन किया। रेंसकॉग का प्रोजेक्ट 10 साल तक चला। लेकिन एमवीसी के बारे में पहला प्रकाशन 10 साल बाद प्रकाश में आया। मार्टिन फाउलर, सॉफ्टवेयर आर्किटेक्चर पर कई पुस्तकों और लेखों के लेखक, उल्लेख करता है कि उन्होंने स्मॉलटाक के कार्यशील संस्करण का उपयोग करके एमवीसी का अध्ययन किया। क्योंकि मूल स्रोत से एमवीसी के बारे में लंबे समय तक कोई जानकारी नहीं थी, और कई अन्य कारणों से, इस अवधारणा की बड़ी संख्या में विभिन्न व्याख्याएं सामने आईं। परिणामस्वरूप, कई लोग MVC को एक डिज़ाइन पैटर्न मानते हैं। कम सामान्यतः, एमवीसी को एक समग्र पैटर्न या कई पैटर्नों का संयोजन कहा जाता है जो जटिल अनुप्रयोगों को बनाने के लिए मिलकर काम करते हैं। लेकिन, जैसा कि पहले उल्लेख किया गया है, MVC वास्तव में मुख्य रूप से वास्तुशिल्प विचारों/सिद्धांतों/दृष्टिकोणों का एक सेट है जिसे विभिन्न पैटर्न का उपयोग करके विभिन्न तरीकों से लागू किया जा सकता है... अगला, हम MVC अवधारणा में अंतर्निहित मुख्य विचारों पर विचार करेंगे। और कई अन्य कारणों से, इस अवधारणा की बड़ी संख्या में विभिन्न व्याख्याएँ सामने आईं। परिणामस्वरूप, कई लोग MVC को एक डिज़ाइन पैटर्न मानते हैं। कम सामान्यतः, एमवीसी को एक समग्र पैटर्न या कई पैटर्नों का संयोजन कहा जाता है जो जटिल अनुप्रयोगों को बनाने के लिए मिलकर काम करते हैं। लेकिन, जैसा कि पहले उल्लेख किया गया है, MVC वास्तव में मुख्य रूप से वास्तुशिल्प विचारों/सिद्धांतों/दृष्टिकोणों का एक सेट है जिसे विभिन्न पैटर्न का उपयोग करके विभिन्न तरीकों से लागू किया जा सकता है... अगला, हम MVC अवधारणा में अंतर्निहित मुख्य विचारों पर विचार करेंगे। और कई अन्य कारणों से, इस अवधारणा की बड़ी संख्या में विभिन्न व्याख्याएँ सामने आईं। परिणामस्वरूप, कई लोग MVC को एक डिज़ाइन पैटर्न मानते हैं। कम सामान्यतः, एमवीसी को एक समग्र पैटर्न या कई पैटर्नों का संयोजन कहा जाता है जो जटिल अनुप्रयोगों को बनाने के लिए मिलकर काम करते हैं। लेकिन, जैसा कि पहले उल्लेख किया गया है, MVC वास्तव में मुख्य रूप से वास्तुशिल्प विचारों/सिद्धांतों/दृष्टिकोणों का एक सेट है जिसे विभिन्न पैटर्न का उपयोग करके विभिन्न तरीकों से लागू किया जा सकता है... अगला, हम MVC अवधारणा में अंतर्निहित मुख्य विचारों पर विचार करेंगे।

एमवीसी: मूल विचार और सिद्धांत

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

चरण 1. एप्लिकेशन के व्यावसायिक तर्क को उपयोगकर्ता इंटरफ़ेस से अलग करें

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

चरण 2 मॉडल को और अधिक स्वतंत्र बनाने और उपयोगकर्ता इंटरफ़ेस को सिंक्रनाइज़ करने के लिए पर्यवेक्षक पैटर्न का उपयोग करें

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

चरण 3 इंटरफ़ेस को दृश्य और नियंत्रक में अलग करें

हम एप्लिकेशन को मॉड्यूल में विभाजित करना जारी रखते हैं, लेकिन अब पदानुक्रम में निचले स्तर पर हैं। इस चरण में, उपयोगकर्ता इंटरफ़ेस (जिसे हमने चरण 1 में एक अलग मॉड्यूल में विभाजित किया था) को एक दृश्य और एक नियंत्रक में विभाजित किया गया है। दृश्य और नियंत्रक के बीच एक सख्त रेखा खींचना कठिन है। यदि हम कहते हैं कि दृश्य वह है जो उपयोगकर्ता देखता है, और नियंत्रक वह तंत्र है जो उपयोगकर्ता को सिस्टम के साथ बातचीत करने की अनुमति देता है, तो आप एक विरोधाभास की ओर इशारा कर सकते हैं। नियंत्रण तत्व, जैसे किसी वेब पेज पर बटन या फ़ोन की स्क्रीन पर वर्चुअल कीबोर्ड, मूल रूप से नियंत्रक का हिस्सा होते हैं। लेकिन वे उपयोगकर्ता को दृश्य के किसी भी भाग के रूप में दिखाई देते हैं। हम वास्तव में यहाँ जिस बारे में बात कर रहे हैं वह कार्यात्मक पृथक्करण है। उपयोगकर्ता इंटरफ़ेस का मुख्य कार्य सिस्टम के साथ उपयोगकर्ता की सहभागिता को सुविधाजनक बनाना है।
  • आउटपुट और आसानी से उपयोगकर्ता को सिस्टम जानकारी प्रदर्शित करता है
  • उपयोगकर्ता डेटा और कमांड दर्ज करें (उन्हें सिस्टम में संचार करें)
ये कार्य निर्धारित करते हैं कि उपयोगकर्ता इंटरफ़ेस को मॉड्यूल में कैसे विभाजित किया जाना चाहिए। अंत में, सिस्टम आर्किटेक्चर इस तरह दिखता है: भाग 7. एमवीसी (मॉडल-व्यू-कंट्रोलर) पैटर्न - 4 का परिचयऔर इस तरह हम मॉडल, व्यू और कंट्रोलर नामक तीन मॉड्यूल वाले एप्लिकेशन पर पहुंचते हैं। आइए संक्षेप करते हैं:
  1. एमवीसी प्रतिमान के सिद्धांतों के अनुसार, एक प्रणाली को मॉड्यूल में विभाजित किया जाना चाहिए।
  2. सबसे महत्वपूर्ण और स्वतंत्र मॉड्यूल मॉडल होना चाहिए।
  3. मॉडल प्रणाली का मूल है। उपयोगकर्ता इंटरफ़ेस से इसे स्वतंत्र रूप से विकसित और परीक्षण करना संभव होना चाहिए।
  4. इसे प्राप्त करने के लिए, विभाजन के पहले चरण में, हमें सिस्टम को एक मॉडल और यूजर इंटरफेस में विभाजित करने की आवश्यकता है।
  5. फिर, पर्यवेक्षक पैटर्न का उपयोग करके, हम मॉडल की स्वतंत्रता को बढ़ाते हैं और उपयोगकर्ता इंटरफ़ेस को सिंक्रनाइज़ करते हैं।
  6. तीसरा कदम यूजर इंटरफेस को कंट्रोलर और व्यू में विभाजित करना है।
  7. सिस्टम में उपयोगकर्ता डेटा प्राप्त करने के लिए जो कुछ भी आवश्यक है वह नियंत्रक में है।
  8. उपयोगकर्ता को जानकारी देने के लिए जो कुछ भी आवश्यक है, वह दृश्य में है।
अपनी हॉट चॉकलेट पीने से पहले बस एक और महत्वपूर्ण बात पर चर्चा करें।

व्यू और कंट्रोलर मॉडल के साथ कैसे इंटरैक्ट करते हैं, इसके बारे में थोड़ा सा

नियंत्रक के माध्यम से जानकारी दर्ज करके, उपयोगकर्ता मॉडल को बदल देता है। या कम से कम, उपयोगकर्ता मॉडल डेटा को बदलता है। जब उपयोगकर्ता इंटरफ़ेस तत्वों (दृश्य के माध्यम से) के माध्यम से जानकारी प्राप्त करता है, तो उपयोगकर्ता मॉडल के बारे में जानकारी प्राप्त कर रहा होता है। यह कैसे होता है? किस माध्यम से व्यू और कंट्रोलर मॉडल के साथ इंटरैक्ट करते हैं? आखिरकार, डेटा पढ़ने/लिखने के लिए दृश्य की कक्षाएं सीधे मॉडल की कक्षाओं के तरीकों को कॉल नहीं कर सकती हैं। अन्यथा, हम यह नहीं कह पाएंगे कि मॉडल स्वतंत्र है। मॉडल बारीकी से संबंधित वर्गों का एक सेट है, जिसे न तो दृश्य और न ही नियंत्रक तक पहुंच प्राप्त होनी चाहिए। मॉडल को दृश्य और नियंत्रक से जोड़ने के लिए, हमें मुखौटा डिजाइन पैटर्न को लागू करने की आवश्यकता है। मॉडल का मुखौटा मॉडल और यूजर इंटरफेस के बीच की परत है, जिसके माध्यम से दृश्य आसानी से स्वरूपित डेटा प्राप्त करता है, और नियंत्रक मुखौटा पर आवश्यक विधियों को कॉल करके डेटा को बदलता है। अंत में, सब कुछ इस तरह दिखता है: भाग 7. एमवीसी (मॉडल-व्यू-कंट्रोलर) पैटर्न - 6 का परिचय

एमवीसी: हम क्या हासिल करते हैं?

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