आर्किटेक्चर में एक लचीली प्लग-इन कैसे बनाएं?


154

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

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

जैसा कि मैंने विभिन्न आर्किटेक्चर से सीखना चाहा है, जिनके साथ मैंने काम किया है, मैं सुझाव के लिए समुदाय को भी देख रहा हूं। आपने SOLID प्लग-इन आर्किटेक्चर को कैसे लागू किया है? आपकी सबसे बुरी विफलता (या आपके द्वारा देखी गई सबसे बुरी विफलता) क्या थी? यदि आप नए प्लग-इन आर्किटेक्चर को लागू करने जा रहे हैं तो आप क्या करेंगे? एसडीके या ओपन सोर्स प्रोजेक्ट जो आपने साथ काम किया है, एक अच्छी वास्तुकला का सबसे अच्छा उदाहरण है?

कुछ उदाहरण जो मैं अपने दम पर पा रहा हूँ:

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


क्या आप कह सकते हैं कि प्लगइन आर्किटेक्चर एक सामान्य विषय क्यों रहा है? यह किन समस्याओं को हल करता है, या लक्ष्यों को संबोधित करता है? कई एक्स्टेंसिबल सिस्टम / एप्लिकेशन कुछ फॉर्म के प्लगइन्स का उपयोग करते हैं, लेकिन समस्या हल होने के आधार पर फॉर्म काफी भिन्न होता है।
mdma

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

जवाबों:


89

यह एक उत्तर के रूप में ज्यादा उपयोगी उपयोगी टिप्पणी / उदाहरणों का एक गुच्छा नहीं है।

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

  • एक आवेदन जो मैंने थोड़ा बढ़ाया है वह है Trac । इसमें एक घटक वास्तुकला है जो इस स्थिति में इसका मतलब है कि कार्यों को विस्तार बिंदुओं को विज्ञापित करने वाले मॉड्यूल को सौंपा गया है। फिर आप अन्य घटकों को लागू कर सकते हैं जो इन बिंदुओं में फिट होंगे और प्रवाह को बदल देंगे। यह थोड़ा ऊपर कल्कि के सुझाव जैसा है।

  • एक और अच्छा है जो py.test है । यह "सर्वश्रेष्ठ एपीआई कोई एपीआई नहीं है" दर्शन का अनुसरण करता है और हर स्तर पर बुलाए जाने वाले हुक पर पूरी तरह निर्भर करता है। आप एक कन्वेंशन के अनुसार नामित फ़ाइलों / कार्यों में इन हुक को ओवरराइड कर सकते हैं और व्यवहार को बदल सकते हैं। आप साइट पर प्लगइन्स की सूची देख सकते हैं कि वे कितनी जल्दी / आसानी से कार्यान्वित हो सकते हैं।

कुछ सामान्य बिंदु।

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

1
मैं स्क्रिप्टिंग भाषा बिंदु का विस्तार करूंगा कि यह अजगर या पर्ल जैसी मौजूदा भाषा को एम्बेड करने पर विचार करने के लायक है
रुडी

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

24

अपने अनुभव में मैंने पाया है कि वास्तव में दो प्रकार के प्लग-इन आर्किटेक्चर हैं।

  1. एक इस प्रकार है Eclipse modelजो स्वतंत्रता की अनुमति देने के लिए है और खुले अंत में है।
  2. दूसरे को आमतौर पर प्लगइन्स का पालन करने की आवश्यकता होती है narrow APIक्योंकि प्लगइन एक विशिष्ट फ़ंक्शन को भर देगा।

इसे अलग तरीके से बताने के लिए , एक प्लगिन आपके एप्लिकेशन को एक्सेस करने की अनुमति देता है जबकि दूसरा आपके एप्लिकेशन को प्लगइन्स एक्सेस करने की अनुमति देता है

भेद सूक्ष्म है, और कभी-कभी कोई भेद नहीं होता है ... आप अपने आवेदन के लिए दोनों चाहते हैं।

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

येज के गुण ब्लॉग इस बारे में थोड़ी बात करता है कि कैसे गुणों के पैटर्न का उपयोग प्लगइन्स और एक्स्टेंसिबिलिटी के लिए अनुमति देता है।

मैंने जो भी काम किया है, उसमें से अधिकांश में आर्किटेक्चर ने मेरे ऐप को प्लगइन्स, टाइम / डिस्प्ले / मैप डेटा आदि जैसी चीजों को एक्सेस करने की अनुमति दी है।

वर्षों पहले मैं कारखानों, प्लगइन प्रबंधकों और इन सभी का प्रबंधन करने के लिए फ़ाइलों को कॉन्फ़िगर करता हूं और मुझे यह निर्धारित करने देता है कि रनटाइम में किस प्लगइन का उपयोग करना है।

  • अब मैं आमतौर पर बस DI frameworkउस काम को करता हूं।

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


@ जस्टिन हां, डि = निर्भरता इंजेक्शन।
व्युत्पत्ति

14

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

http://www.eclipse.org/articles/Article-Plug-in-architecture/plugin_architecture.html


निश्चित रूप से एक अच्छा उदाहरण है, लेकिन क्या कई अनुप्रयोगों की तुलना में यह बड़ा और अधिक जटिल है?
justkt

हाँ, यह हो सकता है, लचीलेपन में वृद्धि लागत के साथ आती है। लेकिन मुझे लगता है कि यह एक अलग दृष्टिकोण दिखाता है। आप के मेनू का मेन्यू प्लग-इन या मुख्य दृश्य क्यों नहीं बन सका?
पैट्रिक

6
समान दृष्टिकोण (सब कुछ एक प्लगइन है) का उपयोग सिम्फनी फ्रेमवर्क के नए संस्करण में किया जाता है। उन्हें बंडल कहा जाता है लेकिन सिद्धांत समान है। यह वास्तुकला काफी सरल है, शायद आपको इस पर एक नज़र रखना चाहिए: symfony-reloaded.org/quick-tour-part-4
Marijn Huizendveld

@Marjin Huizendveld - आपको इसे एक अलग उत्तर के रूप में जोड़ना चाहिए ताकि मैं उत्तर को बढ़ा सकूं। एक दिलचस्प रूपरेखा की तरह लग रहा है!
justkt

11

मैं एक काफी सरल तकनीक का वर्णन करता हूं जिसका उपयोग मैंने अतीत में किया है। यह दृष्टिकोण प्लगइन लोडिंग प्रक्रिया में मदद करने के लिए C # प्रतिबिंब का उपयोग करता है। इस तकनीक को संशोधित किया जा सकता है इसलिए यह C ++ पर लागू होता है लेकिन आप प्रतिबिंब का उपयोग करने में सक्षम होने की सुविधा खो देते हैं।

एक IPluginइंटरफ़ेस का उपयोग उन वर्गों की पहचान करने के लिए किया जाता है जो प्लगइन्स को लागू करते हैं। प्लगइन के साथ संवाद करने की अनुमति देने के लिए इंटरफ़ेस में तरीके जोड़े जाते हैं। उदाहरण के लिए जिस Initविधि का उपयोग करने के लिए प्लगइन को इनिशियलाइज़ करने का निर्देश देगा।

प्लगइन्स को खोजने के लिए एप्लिकेशन .Net असेंबलियों के लिए एक प्लगइन फ़ोल्डर को स्कैन करता है। प्रत्येक विधानसभा भरी हुई है। रिफ्लेक्शन का उपयोग उन वर्गों के लिए स्कैन करने के लिए किया जाता है जो लागू करते हैं IPlugin। प्रत्येक प्लगइन वर्ग का एक उदाहरण बनाया गया है।

(वैकल्पिक रूप से, एक Xml फ़ाइल लोड करने के लिए असेंबली और कक्षाओं को सूचीबद्ध कर सकती है। यह प्रदर्शन में मदद कर सकता है लेकिन मुझे प्रदर्शन के साथ कोई समस्या नहीं मिली)।

Initविधि प्रत्येक प्लगइन वस्तु के लिए कहा जाता है। यह एक ऐसी वस्तु के संदर्भ में दिया जाता है जो एप्लिकेशन इंटरफ़ेस को लागू करता है: IApplication(या आपके ऐप के लिए विशिष्ट नाम कुछ और, जैसे ITextEditorApplication)।

IApplicationऐसी विधियाँ शामिल हैं जो प्लगइन को एप्लिकेशन के साथ संवाद करने की अनुमति देती है। उदाहरण के लिए यदि आप एक टेक्स्ट एडिटर लिख रहे हैं, तो इस इंटरफ़ेस में एक OpenDocumentsसंपत्ति होगी जो प्लगइन्स को वर्तमान में खुले दस्तावेजों के संग्रह को फिर से शुरू करने की अनुमति देती है।

इस प्लगइन सिस्टम को एक व्युत्पन्न प्लगइन वर्ग, जैसे LuaPluginकि आगे की IPluginफ़ंक्शन और एक Lua स्क्रिप्ट के लिए एप्लिकेशन इंटरफ़ेस बनाकर, स्क्रिप्टिंग भाषाओं, जैसे Lua तक बढ़ाया जा सकता है ।

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


7

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

यदि आप रुचि रखते हैं और अधिक पढ़ें ...


धन्यवाद, दिलचस्प लग रहा है। अन्य भाषाओं में समान प्रिंसिपल लागू करना कितना आसान है?
justkt

वास्तव में MEF केवल .NET फ्रेमवर्क के लिए है मुझे अन्य फ्रेमवर्क के बारे में कुछ भी पता नहीं है
BALKANGraph

7

मैंने एक बार एक ऐसी परियोजना पर काम किया था जिसमें प्रत्येक ग्राहक को सिस्टम को सेटअप करने के तरीके में इतना लचीला होना चाहिए था, जो कि हमें मिला एक अच्छा डिज़ाइन ग्राहक को C # संकलक बनाना था!

यदि कल्पना शब्दों से भरी हुई है:

  • लचीला
  • लगाना
  • अनुकूलन

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

ग्राहकों का समर्थन (या फाउंटेन-लाइन समर्थन लोगों) प्लग-इन लिखना आर्किटेक्चर की तुलना में बहुत कठिन है


5

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

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

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

पैकेजिंग प्लगइन्स का साधन काफी हद तक व्यक्तिगत पसंद पर निर्भर करता है, लेकिन आप एक सरल इंटरफ़ेस के साथ संपीड़ित संग्रह के साथ कभी भी गलत नहीं हो सकते हैं, PluginName.extरूट डायरेक्टरी में कह सकते हैं ।


3

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

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

  • आप "प्लगइन प्रकार विज्ञापन के रूप में इंटरफ़ेस" तंत्र के लिए कंटेनर को स्कैन कर सकते हैं।
  • आप सामान्य निर्भरता को इंजेक्ट करने के लिए कंटेनर का उपयोग कर सकते हैं, जिसके लिए प्लगइन्स की आवश्यकता हो सकती है (जैसे कि रिसोर्सब्लडवेयर या मैसेज सोर्सवेयर)।

1

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

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