कैसे ठीक से winform में एक परियोजना की संरचना करने के लिए?


26

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

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

प्रोजेक्ट फ़ोल्डर का ठीक से पुनर्गठन कैसे करें?

फिलहाल मैं कुछ इस तरह से सोच रहा हूं:

  • प्रपत्रों के लिए फ़ोल्डर बनाएँ
  • उपयोगिता वर्गों के लिए फ़ोल्डर बनाएँ
  • केवल डेटा वाले वर्गों के लिए फ़ोल्डर बनाएँ

वर्गों को जोड़ने पर नामकरण सम्मेलन क्या है?

क्या मुझे कक्षाओं का भी नाम बदल देना चाहिए ताकि उनकी कार्यक्षमता को उनके नाम को देखकर पहचाना जा सके? उदाहरण के लिए, सभी फॉर्म कक्षाओं का नाम बदलकर, ताकि उनका नाम फॉर्म के साथ समाप्त हो जाए । या क्या यह आवश्यक नहीं है यदि उनके लिए विशेष फ़ोल्डर बनाए जाते हैं?

क्या करें, ताकि मुख्य फॉर्म के सभी कोड Form1.cs में समाप्त न हों

मेरे सामने एक और समस्या यह है कि जैसा कि मुख्य रूप से मेरे द्वारा जोड़े जाने वाले प्रत्येक फीचर के साथ और अधिक बड़े पैमाने पर हो रहा है, कोड फ़ाइल (Form1.cs) वास्तव में बड़ी हो रही है। मेरे पास उदाहरण के लिए एक TabControl है और प्रत्येक टैब में नियंत्रणों का गुच्छा है और सभी कोड Form1.cs में समाप्त हो गए हैं। इससे कैसे बचा जाए?

इसके अलावा, क्या आप किसी भी लेख या पुस्तकों को जानते हैं जो इन समस्याओं से निपटते हैं?

जवाबों:


24

ऐसा लगता है कि आप कुछ सामान्य नुकसान में गिर गए हैं, लेकिन चिंता न करें, उन्हें ठीक किया जा सकता है :)

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

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

यहां वास्तविक चाल यह है कि आप नियंत्रणों के बीच संचार का प्रबंधन कैसे करते हैं। आप नहीं चाहते कि फार्म पर 30 उपयोगकर्ता नियंत्रण सभी बेतरतीब ढंग से एक-दूसरे के संदर्भों को पकड़े और उन पर कॉल करने के तरीके।

इसलिए आप प्रत्येक नियंत्रण के लिए एक इंटरफ़ेस बनाते हैं। इंटरफ़ेस में ऑपरेशन शामिल हैं जो नियंत्रण स्वीकार करेगा और किसी भी घटना को उठाएगा। जब आप इस ऐप के बारे में सोचते हैं, तो आपको परवाह नहीं है कि सूची बॉक्स सूची चयन में परिवर्तन होता है, आप इस तथ्य में रुचि रखते हैं कि एक नया उपयोगकर्ता बदल गया है।

इसलिए हमारे उदाहरण ऐप का उपयोग करते हुए, उपयोगकर्ताओं के सूची बॉक्स को नियंत्रित करने वाले नियंत्रण के लिए पहला इंटरफ़ेस उपयोगकर्ताचेंज नामक एक घटना को शामिल करेगा जो एक उपयोगकर्ता ऑब्जेक्ट को पास करता है।

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

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

प्रत्येक नियंत्रण को अब एक व्यू (वीवीपी में वी) कहा जाता है और हमने पहले से ही अधिकांश को कवर किया है जो ऊपर आवश्यक है। इस मामले में, नियंत्रण और इसके लिए एक इंटरफ़ेस।

हम जो कुछ जोड़ रहे हैं वह मॉडल और प्रस्तुतकर्ता है।

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

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

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

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

प्रस्तुतकर्ता के पास CanEditUser जैसे गुण भी होंगे, जो उपयोगकर्ता द्वारा संपादित किए जाने पर सही वापस आ जाएगा। इसके बाद व्यू को हर बार जानना होगा। आप काले रंग में संपादन योग्य चाहते हैं और केवल ग्रे में पढ़ सकते हैं। तकनीकी रूप से यह दृश्य के लिए एक निर्णय है क्योंकि यह यूआई केंद्रित है, चाहे उपयोगकर्ता पहली बार में प्रस्तुतकर्ता के लिए संपादन योग्य हो। प्रस्तुतकर्ता जानता है क्योंकि यह मॉडल से बात करता है।

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


8

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

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

  • आश्रित विधानसभाओं के सभी से विभिन्न अनुप्रयोग घटकों को बनाना और आरंभ करना
  • किसी भी तीसरे पक्ष के घटकों को कॉन्फ़िगर करना जो संपूर्ण अनुप्रयोग पर निर्भर करता है (जैसे नैदानिक ​​उत्पादन के लिए Log4Net)
  • मैं भी शायद "सभी अपवादों को पकड़ता हूँ और स्टैक ट्रेस रिकॉर्ड करता हूँ" मुख्य फ़ंक्शन में कोड का एक सा प्रकार है जो किसी भी अप्रत्याशित महत्वपूर्ण / घातक विफलताओं की परिस्थितियों को लॉग करने में मदद करेगा।

के रूप में खुद को आवेदन घटकों के लिए, मैं आमतौर पर एक छोटे से आवेदन में कम से कम तीन के लिए लक्ष्य

  • डेटा एक्सेस लेयर (डेटाबेस कनेक्शन, फ़ाइल एक्सेस, आदि) - एप्लिकेशन द्वारा उपयोग किए गए किसी भी निरंतर / संग्रहीत डेटा की जटिलता के आधार पर, इनमें से कई विधानसभाएं हो सकती हैं - मैं संभवतः डेटाबेस हैंडलिंग के लिए एक अलग असेंबली बनाऊंगा (संभवतः कई) असेंबली अगर डेटाबेस के साथ बातचीत में कुछ भी जटिल है - जैसे कि यदि आप बुरी तरह से डिज़ाइन किए गए डेटाबेस के साथ स्टुक्स हैं, तो आपको कोड में DB संबंधों को संभालने की आवश्यकता हो सकती है, इसलिए प्रविष्टि और पुनर्प्राप्ति के लिए कई मॉड्यूल लिखने का मतलब हो सकता है)

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

  • प्रस्तुति परत (यानी GUI); एक छोटे से आवेदन में, संवाद बॉक्स के एक जोड़े के साथ बस एक "मुख्य रूप" हो सकता है जो सभी एक ही विधानसभा में जा सकते हैं - एक बड़े आवेदन में, जीयूआई के पूरे कार्यात्मक भागों के लिए अलग-अलग विधानसभाएं हो सकती हैं। यहां कक्षाएं उपयोगकर्ता इंटरैक्शन कार्य करने की तुलना में थोड़ा अधिक करेंगी - यह कुछ मूल इनपुट सत्यापन के साथ एक शेल की तुलना में थोड़ा अधिक होगा, किसी भी एनीमेशन को संभालना, आदि किसी भी घटना / बटन पर क्लिक करें जो "कुछ करें" को आगे बढ़ाया जाएगा। लॉजिक लेयर (इसलिए मेरी प्रेजेंटेशन लेयर में सख्ती से कोई भी लॉजिक लॉजिक नहीं होगा, लेकिन इसमें लॉजिक लेयर पर किसी GUI कोड का बोझ भी नहीं होगा - इसलिए प्रेजेंटेशन असेंबली में कोई प्रोग्रेस बार या अन्य फैंसी सामान भी बैठ जाएगा / एँ)

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

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

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

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


4

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

वर्गों को जोड़ने पर नामकरण सम्मेलन क्या है?

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

बहुत से लोग बहुवचन (जैसे ग्राहक) में सार्थक छोटी संज्ञाओं का उपयोग करते हैं। कुछ नाम संबंधित डेटाबेस तालिका के लिए एकवचन नाम के करीब हो (यदि आप वस्तुओं और तालिकाओं के बीच 1-1 मानचित्रण का उपयोग करते हैं)।

नामकरण कक्षाओं के लिए कई स्रोत हैं, उदाहरण के लिए एक नज़र डालें:। नेट नामकरण परंपराएँ और प्रोग्रामिंग मानक - सर्वोत्तम अभ्यास और / या STOVF-C # कोडिंग दिशानिर्देश

क्या करें, ताकि मुख्य फॉर्म के सभी कोड Form1.cs में समाप्त न हों

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

एमएस विंडोज फॉर्म की घटना-एक्शन प्रकृति के कारण, ऐसा कुछ भी नहीं है जो मुझे पता है कि अस्पष्टता और प्रयास को जोड़े बिना कोड को मुख्य रूप से दूर ले जाने में आपकी मदद कर सकता है। हालांकि, एमवीवीएम एक विकल्प हो सकता है (भविष्य की परियोजनाओं में), उदाहरण के लिए देखें: विंडोज फॉर्म के लिए एमवीवीएम


2

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

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

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


1

एक परियोजना की संरचना पूरी तरह से परियोजना और उसके आकार पर निर्भर करती है, हालांकि आप कुछ फ़ोल्डर्स जैसे जोड़ सकते हैं

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

आपको किसी भी प्रकार के फ़ोल्डर में फ़ॉर्म डालने की आवश्यकता नहीं है, बस अपने प्रपत्रों का नाम बदलें। मेरा मतलब है कि इसका सामान्य ज्ञान कोई नहीं जानता है कि आपके रूपों को किस नाम से बेहतर होना चाहिए।

नामकरण सम्मेलन ऐसा है जैसे यदि आपकी कक्षा एक "हैलो वर्ल्ड" संदेश मुद्रित करती है, तो कक्षा का नाम कार्य से संबंधित कुछ होना चाहिए और कक्षा का उपयुक्त नाम HelloWorld.cs होना चाहिए।

आप जैसे भी क्षेत्र बना सकते हैं

#region Hello और फिर endregionअंत में बाहर ।

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

पुस्तकें ? ईआरएम।

कोई भी किताब आपको परियोजनाओं की संरचना नहीं बताती है क्योंकि प्रत्येक परियोजना अलग है, आप इस तरह की चीजों को अनुभव से सीखते हैं।

आशा है कि यह मदद की!

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