2013-02-26 153 views
6

डेल्फी 2010 का उपयोग करके मॉड्यूलर प्लग-इन कैसे बनाएं, मुझे मॉड्यूल या प्लग-इन का समर्थन करने के लिए एक प्रोग्राम लिखने की आवश्यकता है। हालांकि थोड़ा सा योगदान हुआ, मान लें कि मेरे पास एक ऐप है जो डेटाफाइल/टेक्स्ट फाइलों को परिवर्तित करता है। यह आउटपुट के रूप में 30 इनपुट प्रारूपों और उन 30 प्रारूपों का समर्थन करेगा। पहली रिलीज शायद इन प्रारूपों में से कुछ को लागू करेगी। मेरी चुनौती यह है कि मैं डेटा संचालित प्रक्रिया प्रवाह चाहता हूं।डेल्फी

उदाहरण के लिए, मान लें कि मेरे पास PARSE_FILE दिनचर्या है। यदि मेरा इनपुट डेटा फ़ाइल प्रारूप 'Format_A' है, तो फिर जब मैं PARSE_FILE को कॉल करता हूं, तो उसे PARSE_FILE_Format_A का उपयोग करना चाहिए, जैसा कि PARSE_FILE दिनचर्या के अन्य 2 9 विभिन्न संस्करणों के विपरीत है।

PARSE_FILE सिर्फ एक उदाहरण है। मेरे पास शायद 60 अलग-अलग सामान्य फ़ंक्शन, LOAD_FILE, GET_DELIMITER, PARSE_FILE इत्यादि होंगे, लेकिन इनमें से प्रत्येक कार्य 30 अलग-अलग प्रारूपों में से प्रत्येक के लिए थोड़ा अलग होगा। मैं किस तकनीक का उपयोग कर सकता हूं ताकि अगर मैं FORMAT_A के साथ एक फ़ाइल लोड कर रहा हूं, तो इनमें से प्रत्येक 60 अलग-अलग सामान्य दिनचर्या इन 60 दिनचर्या के उचित 'संस्करण' का उपयोग करती है?

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

+3

मैं इंटरफेस के साथ जाना चाहते हैं, एक IMyPlugin इंटरफेस को परिभाषित, वर्ग (ते) है कि इस इंटरफ़ेस को लागू है, प्रत्येक * .dll एक समारोह "RegisterPlugin (AInterface: IMyPlugin)" कहा जाता है का निर्यात करता है, जब अनुप्रयोग शुरू होता है, यह स्कैन करता है फाइलों के लिए "प्लगइन फ़ोल्डर", प्रत्येक "प्लगइन फ़ाइल" (डीएलएल) के लिए, आप इसे लोड करने का प्रयास करते हैं और प्लगइन लोड होने पर इसे "रजिस्टरप्लगिन" फ़ंक्शन कहते हैं, आप डेटा में हेरफेर करने के लिए इंटरफ़ेस पर विधियों को कॉल कर सकते हैं। मेरे 2 सेंट (: ​​ – ComputerSaysNo

+0

आप या तो डीएलएल और COM- संगत 'IInterface' प्रकार (COM-standardized डेटा प्रकारों के साथ जाते हैं, ताकि जब आप EXE और DLL के पास अलग-अलग कंपाइलर संस्करण या विकल्प हों तो आप सबकुछ क्रैश नहीं करेंगे) या आप जाते हैं बीपीएल के साथ, वीसीएल की तरह ही बनाया जाता है। जेडीआईवीसीएल के पास कुछ सरल प्लगइन इंफ्रास्ट्रक्चर है, लेकिन यह आधार रॉकेट साइंस नहीं होगा। हार्ड आईडी प्लानिंग एपीआई और यह हमेशा आपका रचनात्मक काम है। 1 दृष्टिकोण के बारे में अच्छा लेख है, अगर आप कर सकते हैं इसे Google अनुवाद के माध्यम से पढ़ें: http://www.gunsmoker.ru/2011/12/delphi.html –

उत्तर

5
  1. मानक दिनचर्या है कि आप हर प्लगइन एक अंतरफलक प्रकार में लागू करने के लिए मॉड्यूल की आवश्यकता के अपने सेट को परिभाषित करें। कहो, IFileFormatHandler, जो एक होता है PARSE_FILE फ़ंक्शन, आदि
  2. फ़ॉलो करें इंटरफ़ेस डिज़ाइन के सिद्धांतों और कर्तव्यों को अलग करने के सिद्धांतों को एक इंटरफ़ेस में फ़ंक्शंस डालने से बचें कि कुछ कार्यान्वयन में रुचि रखने या लागू करने में सक्षम नहीं होगा। एक अलग इंटरफेस में वैकल्पिक कार्यों को परिभाषित करें कि एक कार्यान्वयन वर्ग लागू करने के लिए चुन सकते हैं या नहीं। उदाहरण के लिए, यदि आप अनुमान लगाते हैं कि कुछ फ़ाइल स्वरूप होंगे जो आपका ऐप पढ़ेगा लेकिन विभिन्न कारणों से लिखने में सक्षम नहीं होंगे, तो आपको एक इंटरफ़ेस में पढ़ने के संचालन करना चाहिए और एक अलग इंटरफ़ेस में ऑपरेशन लिखना चाहिए।
  3. यदि आप डेल्फी में सभी प्लगइन को संलेखित करेंगे, तो आपको सामान्य प्रकारों को साझा करने के लिए बीपीएल पैकेज का उपयोग करना चाहिए। अपने IFileFormatHandler इंटरफ़ेस प्रकार को एक बीपीएल पैकेज (यानी, Common.bpl) में रखें ताकि सभी मॉड्यूल सामान्य इंटरफ़ेस प्रकार का संदर्भ दे सकें। प्रत्येक प्लगइन मॉड्यूल स्वयं अपने बीपीएल पैकेज में भी है। (एक ही बीपीएल पैकेज में एकाधिक फ़ाइल प्रारूप हैंडलर मौजूद हो सकते हैं, लेकिन आधारभूत उदाहरण एक प्रति बीपीएल है)
  4. यदि यह प्लगइन आर्किटेक्चर बनाने में आपका पहला स्विंग है, तो एक ही समय में बहुभाषी समर्थन को कवर करने का प्रयास न करें। अब के लिए डेल्फी के साथ चिपकाओ। डेल्फी में ऐप और मॉड्यूल लिखें। डेल्फी में पूरा करने के लिए एक मॉड्यूलर प्रोजेक्ट बनाएं, फिर एक कदम वापस लें और डेल्फी के अलावा अन्य भाषाओं में लिखे गए मॉड्यूल का समर्थन करने के लिए COM या बाइनरी इंटरफ़ेस आवश्यकताओं को समझने में कुछ समय व्यतीत करें।
  5. आपके सामान्य बीपीएल पैकेज में, एक वैश्विक फ़ंक्शन भी परिभाषित करता है जो मॉड्यूल होस्ट होस्ट - RegisterPlugin(name: string; instance: IFileFormatHandler) उदाहरण के लिए स्वयं को ज्ञात करने के लिए कॉल कर सकता है। यह एक आंतरिक सूची में प्लगइन नाम और उदाहरण पंजीकृत करता है कि मेजबान एप्लिकेशन यह पता लगाने के लिए उपयोग कर सकता है कि कौन से प्लगइन उपलब्ध हैं और उन्हें कॉल करें।
  6. प्रत्येक फ़ाइल हैंडलिंग प्लगइन मॉड्यूल के लिए, एक कक्षा को परिभाषित करें जो साझा बीपीएल पैकेज में परिभाषित सामान्य इंटरफ़ेस लागू करता है। कक्षा के यूनिट प्रारंभिकरण में, मेजबान ऐप के साथ कक्षा को पंजीकृत करने के लिए RegisterPlugion() फ़ंक्शन को कॉल करें।
  7. होस्ट एप्लिकेशन सामान्य पैकेज का उपयोग करता है, और मॉड्यूल पैकेज प्रत्येक सामान्य पैकेज का उपयोग करते हैं।
  8. होस्ट एप्लिकेशन केवल सामान्य इंटरफ़ेस में परिभाषित कार्यों के माध्यम से मॉड्यूल कार्यान्वयन के साथ इंटरैक्ट करता है।
  9. होस्ट एप्लिकेशन आईएस का उपयोग यह जांचने के लिए कर सकता है कि कोई विशेष मॉड्यूल ऑब्जेक्ट उदाहरण वैकल्पिक इंटरफ़ेस लागू करता है, और उस वैकल्पिक इंटरफ़ेस को प्राप्त करने के लिए AS।
  10. इंटरफेस संदर्भ डेल्फी में गिना जाता है, इसलिए जब तक होस्ट एप्लिकेशन मॉड्यूल ऑब्जेक्ट इंस्टेंस (उदाहरण के लिए, रजिस्टरप्लगिन के माध्यम से) के संदर्भ में रखता है, मॉड्यूल इंस्टेंस को जीवंत और स्मृति में रखा जाएगा। जब अंतिम संदर्भ जारी किया जाता है, तो मॉड्यूल इंस्टेंस का निपटारा किया जाएगा।
  11. होस्ट एप्लिकेशन को लोडपैकेज या इसी तरह के एफएन का उपयोग करके रनटाइम पर मॉड्यूल पैकेज बीपीएल को खोजने और लोड करने की आवश्यकता होगी।
  12. ऐप में प्लगइन मॉड्यूल उदाहरणों की एक सूची साझा करना अधिकांश एकल-थ्रेडेड अनुप्रयोगों के लिए ठीक काम करेगा। यदि आप एक साथ कई धागे में इन प्लगइन मॉड्यूल का उपयोग करने की उम्मीद करते हैं, तो स्मृति में मॉड्यूल के सिंगलटन उदाहरणों को रखने के बजाय इस डिज़ाइन को फ़ैक्टरी पैटर्न पर स्थानांतरित करने पर विचार करें। यह एक उदाहरण बनाने के बजाय कारखाने का उपयोग करके उपयोग के धागे के भीतर मांग पर उदाहरणों का निर्माण करके मल्टीथ्रेडिंग का प्रबंधन करने के लिए अधिक आसान और आम तौर पर अधिक प्रदर्शन करने वाला है जो कई धागे से कॉल करने के लिए सुरक्षित होना चाहिए।
+0

यह कड़ाई से कक्षा आधारित प्रतीत होता है। क्या मैं इसे गैर-कक्षा कार्यों के साथ कर सकता हूं? एक संक्षिप्त उदाहरण के लिए, यदि File_FormatA है संसाधित होने पर, हर बार जब मैं मिनमैक्स को कॉल करता हूं, तो File_FormatA से जुड़े किसी का उपयोग करें, लेकिन यदि फ़ाइल_फॉर्मैटबी का उपयोग कर रहा है, तो फ़ाइल_फॉर्मैटबी कोड लाइन में मिले मिनमैक्स का उपयोग करें। (मान लें कि File_FormatA और File_FormatB क्लिप का उपयोग नहीं कर रहे हैं। ऐसा नहीं हो सकता है, लेकिन मैं मैं बस हूँ इस बेहतर समझने के लिए यिंग।) – user1009073

+1

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

+0

असल में बीपीएल-आधारित प्लगइन सिस्टम विकसित करते समय, मैंने ऐसे वैश्विक कार्यों को 'वर्चुअल क्लास विधियों' में व्यवस्थित किया, फिर मैंने उन्हें एकल TClass चर निर्दिष्ट करके एक साथ पास कर दिया। लेकिन कोड पूरा करने के साथ अच्छी तरह से खेलना था :-( –