फ्लेक्स एप्लिकेशन आर्किटेक्चर विकसित करने के लिए पैटर्न का उपयोग करना



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



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





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



छवि



आवेदन को फ्लेक्स (+ AIR रनटाइम) में लिखने का निर्णय लिया गया था। ढांचे में वह सब कुछ है जो हमें चाहिए। AdvancedDataGrid घटक कर्मचारी और प्रोजेक्ट तालिकाओं के लिए आधार के रूप में कार्य करता है। यह रेंडरर्स के कारण बहुत लचीला है और इसमें ड्रैग-एन-ड्रॉप के लिए सुविधाजनक प्लग-इन सपोर्ट है। AIR के पास बहु-विंडो अनुप्रयोगों के लिए समर्थन है और फाइलों के साथ काम करने में सक्षम है।



सबसे पहले, हम बुनियादी आवश्यकताओं को रेखांकित करते हैं।



बुनियादी आवश्यकताओं



1. अनुकूलन लचीलापन देखें

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



2. विभिन्न तार्किक ब्लॉकों के स्वतंत्र समावेश की आसानी और उनके बीच कमांड के प्रसारण की विश्वसनीयता

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



3. आर्किटेक्चर को विश्वसनीयता सुनिश्चित करनी चाहिए

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



प्राप्त आवश्यकताओं के अनुसार विकसित करने के लिए, एक तैयार घटनाओं के आधार पर फ्रेमवर्क का उपयोग कर सकता है, जैसे कि दोस्त, लेकिन जब आप पैटर्न जानते हैं, तो सिस्टम को स्वयं इकट्ठा करना अधिक दिलचस्प है।



1. अनुकूलन लचीलापन देखें


हम एमवीसी के समान एक सर्किट का उपयोग करते हैं। हमारे पास मॉडल, दृश्य और नियंत्रक के समान 3 घटक हैं: DataBuilder , View और Engine

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

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

इंजन (नियंत्रक) व्यापार तर्क से संबंधित है।

यह निम्नलिखित कार्य योजना को दर्शाता है:



इस प्रकार, डेटाब्यूलर-इंजन-व्यू के 2 त्रैमासिक हैं: कर्मचारियों के लिए और परियोजनाओं के लिए। इसके अलावा वास्तुकला में ऐसे सिस्टम हैं जहां कोई दृश्य या डेटाबुलस्टल नहीं है। इसके बारे में नीचे लिखा जाएगा।



2. कार्यक्रम की मॉड्यूलर संरचना इसके भागों के बीच विश्वसनीय संचार के साथ


विभिन्न इंजनों के स्वतंत्र समावेश की आसानी को प्राप्त करना आवश्यक है, और, एक ही समय में, उनके बीच आदेशों के हस्तांतरण की विश्वसनीयता।



हम जिम्मेदारी पैटर्न की श्रृंखला को लागू करते हैं। इंजनों की जंजीर होगी। श्रृंखला का पहला इंजीनियर आदेश भेजता है जो श्रृंखला के साथ अपने गंतव्य तक आगे बढ़ता है।



सबसे पहले, हम पहचानकर्ता सार्वजनिक स्टेटिक कॉन्स्ट टाइप TYPE: स्ट्रिंग में प्रत्येक इंजन को जोड़ते हैं। सभी पहचानकर्ता अलग-अलग होने चाहिए। उनकी विशिष्टता इंजन कारखाने में सत्यापित की जाती है जिसके माध्यम से उन्हें बनाया जाना चाहिए।



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



अब एक चेन बनाते हैं। सभी विशिष्ट इंजन एब्सट्रैक्टाइन वर्ग से विरासत में मिले, जिसमें कई परिभाषित क्षेत्र और विधियां हैं।



- इसके बाद श्रृंखला में अगले तत्व का लिंक होता है।

- सक्रिय (घटना) विधि अमूर्त है। यह उन उपवर्गों में पुनर्परिभाषित किया जाता है जहां प्रत्येक इंजन के लिए विशिष्ट व्यवहार लागू किया जाता है।

- हैंडल (ईवेंट) विधि यह जांचती है कि दिया गया इंजन एक इनकमिंग प्रकार के साथ कमांड को प्रोसेस कर रहा है या नहीं यदि हाँ, सक्रिय () निष्पादित किया जाता है , यदि नहीं , तो श्रृंखला में अगले इंजन के हैंडल () विधि को कहा जाता है।



इस प्रकार, सर्किट में कमांड को स्थानांतरित करने के लिए, आपको केवल रूट तत्व पर हैंडल () को कॉल करने की आवश्यकता है। अनुप्रयोग में कार्य करने के लिए श्रृंखला के लिए , रूट इंजन कमांडवेंट की सदस्यता लेता है :

rootEngine.addEventListener (CommandEvent.ACTIVATE, rootEngine.handle);





एप्लिकेशन में उपयोग किए गए सभी ब्लॉक नीचे दिए गए चित्र में दिखाए गए हैं।







जैसा कि पहले ही उल्लेख किया गया है, इंजन-डेटाबुलस्ट-व्यू के 2 त्रिक हैं: कर्मचारियों के लिए और परियोजनाओं के लिए।



डेटा के बिना एक प्रणाली है: कमांडपैनेल (देखें) और इसे कमांडबाइन । यह प्रत्येक विंडो के शीर्ष पर पैनल है। वह केवल कमांड भेजने से संबंधित है।



दृश्य के बिना एक प्रणाली है: उन वस्तुओं के लिए जो कर्मचारी और परियोजना के बीच संबंध को परिभाषित करते हैं। यह BindsBuilder-BindsEngine की जोड़ी है। संबंध दृश्य EmployeesView और ProjectsView दोनों में शामिल है।



अंत में, प्रस्तुति और डेटा के बिना कई इंजन हैं: InputOutputEngine (एक्सएमएल फाइलों के साथ काम), CSVEngine (तालिकाओं के साथ काम), शॉर्टकट्सइन (गर्म कुंजियों के साथ काम)।



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



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



हमारी वास्तुकला के लाभ


सबसे पहले, श्रृंखला के काम करने के लिए, यह घटना के लिए रूट इंजन पर हस्ताक्षर करने के लिए पर्याप्त है। उसके बाद, आप इंजन को बस श्रृंखला से जोड़कर और हटाकर चालू / बंद कर सकते हैं।



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



इस वास्तुकला का एक और लाभ विकास प्रक्रिया का सरलीकरण है। प्रत्येक इंजन का तर्क समझाया जाता है। इसके लिए धन्यवाद, कई लोग बिना किसी संघर्ष के एक बार में एक आवेदन पर काम कर सकते हैं।



डिस्प्ले लिस्ट ऑब्जेक्ट्स से चेन को कमांड भेजना बहुत आसान है। बुलबुले के साथ एक घटना == असली पॉप अप करने के लिए आवेदन और श्रृंखला में हो जाता है। यहां एक कार्य आरेख है जहां यह माना जाता है कि उपयोगकर्ता किसी एक दृश्य में एक बटन पर क्लिक करता है:



3. समर्थन इतिहास और हॉटकीज़


पिछले कार्यों को पूर्ववत करने की क्षमता के बिना आधुनिक सॉफ्टवेयर में यह कैसे है?

आर्किटेक्चर कहानी समर्थन को जोड़ना आसान बनाता है।



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



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



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



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





स्रोत कोड और निर्देशों के साथ आवेदन Google कोड पर निहित है:

code.google.com/p/easyworkloadtool



निष्कर्ष



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

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



All Articles