新聞中心
1. 概述
在現(xiàn)有軟件開發(fā)中,業(yè)務(wù)越來越復(fù)雜,代碼規(guī)模越來越大,依賴的人力也越來越多。為了降低系統(tǒng)模塊內(nèi)部耦合度,減少開發(fā)難度,也為了能夠支持多團隊的并行開發(fā),插件式開發(fā)架構(gòu)變得愈加流行,尤其是在桌面軟件、移動端應(yīng)用中。對于后端開發(fā),微服務(wù)的形式也越來越流行,但是據(jù)筆者看來,微服務(wù)的很多設(shè)計思路,和插件式開發(fā)架構(gòu)的設(shè)計理念也有相近之處。Eclipse, Visual Studio, VSCode等,都是插件式開發(fā)架構(gòu)的典型案例。

創(chuàng)新互聯(lián)專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、敘州網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城系統(tǒng)網(wǎng)站開發(fā)、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為敘州等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
現(xiàn)代軟件提供插件式開發(fā)架構(gòu),一方面是服務(wù)于產(chǎn)品自身內(nèi)部開發(fā),另外一方面服務(wù)于市場化。借助于市場上各領(lǐng)域開發(fā)人員,在某一款軟件(開源or商業(yè))上進行面向新領(lǐng)域的開發(fā),可以大大提高該產(chǎn)品的市場占有率,并衍生出一系列各領(lǐng)域的代理商及咨詢業(yè)務(wù)。
2. 插件式開發(fā)架構(gòu)要領(lǐng)
不管基于何種語言進行插件式開發(fā)框架的設(shè)計,有一些共同的要點需要具備。
2.1 插件運行主體
基于插件模式進行開發(fā)的軟件,一般會存在一個運行主體。這個載體作為應(yīng)用的主入口,并根據(jù)各類插件的配置信息,將編譯或打包后的插件加載到主體環(huán)境中并執(zhí)行。開發(fā)新的插件,無需調(diào)整現(xiàn)有運行主體的代碼和二進制包。
2.2 插件的注入、配置和初始化
2.2.1 插件配置信息
配置信息即插件的描述信息,可以在代碼中設(shè)置,也可以通過XML文件實現(xiàn),方式不同,目的一致。
- 插件名稱
- 插件版本號
- 插件描述信息
- 依賴的其他插件清單
2.2.2 插件的注入及初始化
插件的注入及初始化一般借助于繼承插件基類,并實現(xiàn)插件框架中指定好的標準接口。通過繼承插件基類,實現(xiàn)插件的注入;通過實現(xiàn)標準的初始化、啟動、關(guān)閉等標準接口,實現(xiàn)插件的生命周期管理工作。
2.2.2.1 插件定義示例
下文代碼是筆者參考開源軟件Xfrogcn.PluginFactory做的說明。
https://gitee.com/WuYeCai/pluginfactory
- 通過C#語言的Attribute特性對插件進行描述
- 通過實現(xiàn)Init, StartAsync, StopAsync標準接口初始化、啟動或關(guān)閉插件。這是對插件生命周期的管理。
- [Plugin(Alias = "PluginA", Description = "測試插件")]
- public class Plugin :: PluginBase, ISupportInitPlugin
- {
- public void Init(IPluginInitContext context)
- {
- //自定義初始化行為
- }
- public override Task StartAsync(IPluginContext context)
- {
- //自定義啟動行為
- return base.StartAsync(context);
- }
- public override Task StopAsync(IPluginContext context)
- {
- //自定義關(guān)閉行為
- return base.StopAsync(context);
- }
- }
2.3. 插件通信機制
插件通信機制是一種通用概念。當各插件間協(xié)同完成一個功能時,彼此進行協(xié)調(diào)互助的一種機制。交互的形式有很多種,一種是插件對外開放自己的接口,接入到服務(wù)總線中供其他插件調(diào)用;一種是提供消息機制,插件之間通過發(fā)送消息進行事件處理。
2.3.1 基于虛擬服務(wù)總線形式的通信機制
基于虛擬服務(wù)總線形式的通信機制,每個插件都有自己的開放接口,這些接口會被注冊到虛擬服務(wù)總線上,其他插件通過虛擬服務(wù)總線,獲取到其他插件的接口服務(wù)。此處涉及到的內(nèi)容是面向接口編程。
2.3.2 插件間消息通信
插件間消息通信屬于一種開發(fā)人員可以自定義的擴展方式,插件運行主體無法定義所有的消息類型及消息的處理方法。所以用戶可以通過約定消息形式以及自定義消息響應(yīng)函數(shù),實現(xiàn)插件間的通信。但是這樣其實增強了插件之間的耦合度,不是特別推薦。筆者建議應(yīng)用層插件盡量只依賴通用服務(wù)型插件及主體運行程序,業(yè)務(wù)插件保持獨立。
3. C++語言下的插件開發(fā)案例
筆者曾基于某國外通用產(chǎn)品,進行領(lǐng)域化定制。該產(chǎn)品基于C++/MFC開發(fā),并提供SDK包和樣例工程,輔助用戶基于該產(chǎn)品的插件開發(fā)。每個插件最終會編譯為一個DLL,拷貝到產(chǎn)品指定目錄下,就會被加載并執(zhí)行。整體模式如下圖所示。
- 支持插件注入接口
通過繼承插件中指定的基類并實現(xiàn)指定接口,達到插件注冊及初始化的效果。
- 支持用于注入菜單及子菜單的接口
通過菜單注入接口,開發(fā)人員可以在菜單中提供插件功能入口。用戶可以通過該入口啟用該插件。
- 支持事件分發(fā)(已定義標準事件清單),插件可以接收事件,并開發(fā)自定義的事件處理程序
用戶在實際設(shè)計過程中針對模型、針對工程目錄、針對繪圖區(qū)域的操作,會分發(fā)到所有的插件中,類似于廣播。開發(fā)人員根據(jù)實際需要去實現(xiàn)或者不實現(xiàn)。
- 提供接口,獲取當前上下文信息
提供訪問接口,用戶獲取用戶當前選中的模型對象、選中的目錄、選中的文件等信息。
- 提供接口,用于所有業(yè)務(wù)對象的訪問
提供訪問接口,可以去創(chuàng)建、刪除模型,創(chuàng)建、刪除文件,創(chuàng)建刪除工程管理目錄等文件。
- 插件以DLL的形式存在,進程內(nèi)加載運行
4. JAVA體系下的插件開發(fā)案例
校園時代曾和同學(xué)一起開發(fā)過一款桌面端設(shè)計軟件,就是基于Eclipse的RCP技術(shù)?;诓寮募軜?gòu)、擴展點等概念,依舊印象深刻。其中開發(fā)的基石Eclipse,就是基于OSGI規(guī)范進行開發(fā)。
4.1 OSGI簡介
OSGi是基于java語言實現(xiàn)的開發(fā)期和運行期模塊化技術(shù)。它的核心部分是一個框架,其中定義了應(yīng)用程序的生命周期模式和服務(wù)注冊。OSGI框架定義了大量的OSGI通用服務(wù):日志、配置管理,XML解析等通用服務(wù)。
4.2 OSGI整體架構(gòu)
4.2.1 模塊層
模塊層可以理解為開發(fā)出來的各類插件,一般以bundle的形式出現(xiàn)。一個完整的系統(tǒng)功能,往往由不同的模塊插件進行配合完成。模塊之間通過約定好的接口為外部提供服務(wù)。也確定了每個模塊的邊界,并進行封裝。
模塊層中bundle的特點:
- bundle 以 jar 包形式存在的模塊化物理單元,包含了代碼,資源文件和元數(shù)據(jù)(模塊描述信息)。
- bundle 是開發(fā)、部署 OSGi 應(yīng)用的基本單元。
- bundle 的核心是 META-NF 目錄下的 MANIFEST.MF 文件。
- bundle 定義了內(nèi)部包的對外可見性。
- 每個 bundle 都有單獨的類加載器。
4.2.2 生命周期層
管理bundle的創(chuàng)建,銷毀。Bundle內(nèi)部需要實現(xiàn)相關(guān)的接口,配合生命周期層的工作。
4.3.3 服務(wù)層
服務(wù)層可以理解為一個服務(wù)中心,每個插件將自己可以對外提供的功能通過服務(wù)層進行發(fā)布,并給其他插件提供了服務(wù)發(fā)現(xiàn)的方式及服務(wù)訪問。
4.3 Eclipse插件示例
Eclipse插件示例,采用Eclipse中自帶的Hello World案例進行說明。
插件的配置信息如下:
- Manifest-Version: 1.0
- Bundle-ManifestVersion: 2
- Bundle-Name: PluginDemo
- Bundle-SymbolicName: PluginDemo
- Bundle-Version: 1.0.0.qualifier
- Bundle-Activator: plugindemo.Activator
- Bundle-RequiredExecutionEnvironment: JavaSE-16
- Automatic-Module-Name: PluginDemo
- Import-Package: org.osgi.framework;version="1.3.0"
- Bundle-ActivationPolicy: lazy
一個簡單的插件示例代碼如下:
- package plugindemo;
- import org.osgi.framework.BundleActivator;
- import org.osgi.framework.BundleContext;
- public class Activator implements BundleActivator {
- @Override
- public void start(BundleContext context) throws Exception {
- System.out.println("Hello World!!");
- }
- @Override
- public void stop(BundleContext context) throws Exception {
- System.out.println("Goodbye World!!");
- }
- }
采用Eclipse OSGI模式進行運行,結(jié)果輸入如下。
- WARNING: Using incubator modules: jdk.incubator.vector, jdk.incubator.foreign
- Hello World!!
- osgi> 22:48:00.337 [Worker-0: Loading available Gradle versions] INFO org.eclipse.buildship.core.internal.util.gradle.PublishedGradleVersions - Gradle version information cache is up-to-date. Trying to read.
- !SESSION 2021-08-31 22:47:57.492 -----------------------------------------------
5. 總結(jié)
本文簡單說明了插件開發(fā)架構(gòu)中的一些基本原則,以及采用不同語言開發(fā)的軟件平臺中的插件開發(fā)模式。需要注意的是,實際插件架構(gòu)中,根據(jù)產(chǎn)品的不同、面向的領(lǐng)域不同、采用的編程語言不同,會有很多不一樣的設(shè)計,需要結(jié)合具體情況進行設(shè)計。
網(wǎng)站題目:插件式開發(fā)架構(gòu)綜述
URL標題:http://m.fisionsoft.com.cn/article/djdgjci.html


咨詢
建站咨詢
