自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

插件式開(kāi)發(fā)架構(gòu)綜述

開(kāi)發(fā) 架構(gòu)
現(xiàn)代軟件提供插件式開(kāi)發(fā)架構(gòu),一方面是服務(wù)于產(chǎn)品自身內(nèi)部開(kāi)發(fā),另外一方面服務(wù)于市場(chǎng)化。

[[421758]]

1. 概述

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

現(xiàn)代軟件提供插件式開(kāi)發(fā)架構(gòu),一方面是服務(wù)于產(chǎn)品自身內(nèi)部開(kāi)發(fā),另外一方面服務(wù)于市場(chǎng)化。借助于市場(chǎng)上各領(lǐng)域開(kāi)發(fā)人員,在某一款軟件(開(kāi)源or商業(yè))上進(jìn)行面向新領(lǐng)域的開(kāi)發(fā),可以大大提高該產(chǎn)品的市場(chǎng)占有率,并衍生出一系列各領(lǐng)域的代理商及咨詢業(yè)務(wù)。

2. 插件式開(kāi)發(fā)架構(gòu)要領(lǐng)

不管基于何種語(yǔ)言進(jìn)行插件式開(kāi)發(fā)框架的設(shè)計(jì),有一些共同的要點(diǎn)需要具備。

2.1 插件運(yùn)行主體

基于插件模式進(jìn)行開(kāi)發(fā)的軟件,一般會(huì)存在一個(gè)運(yùn)行主體。這個(gè)載體作為應(yīng)用的主入口,并根據(jù)各類插件的配置信息,將編譯或打包后的插件加載到主體環(huán)境中并執(zhí)行。開(kāi)發(fā)新的插件,無(wú)需調(diào)整現(xiàn)有運(yùn)行主體的代碼和二進(jìn)制包。

2.2 插件的注入、配置和初始化

2.2.1 插件配置信息

配置信息即插件的描述信息,可以在代碼中設(shè)置,也可以通過(guò)XML文件實(shí)現(xiàn),方式不同,目的一致。

  • 插件名稱
  • 插件版本號(hào)
  • 插件描述信息
  • 依賴的其他插件清單

2.2.2 插件的注入及初始化

插件的注入及初始化一般借助于繼承插件基類,并實(shí)現(xiàn)插件框架中指定好的標(biāo)準(zhǔn)接口。通過(guò)繼承插件基類,實(shí)現(xiàn)插件的注入;通過(guò)實(shí)現(xiàn)標(biāo)準(zhǔn)的初始化、啟動(dòng)、關(guān)閉等標(biāo)準(zhǔn)接口,實(shí)現(xiàn)插件的生命周期管理工作。

2.2.2.1 插件定義示例

下文代碼是筆者參考開(kāi)源軟件Xfrogcn.PluginFactory做的說(shuō)明。

https://gitee.com/WuYeCai/pluginfactory

  • 通過(guò)C#語(yǔ)言的Attribute特性對(duì)插件進(jìn)行描述
  • 通過(guò)實(shí)現(xiàn)Init, StartAsync, StopAsync標(biāo)準(zhǔn)接口初始化、啟動(dòng)或關(guān)閉插件。這是對(duì)插件生命周期的管理。
  1. [Plugin(Alias = "PluginA", Description = "測(cè)試插件")] 
  2.  public class Plugin :: PluginBase, ISupportInitPlugin 
  3.  { 
  4.     public void Init(IPluginInitContext context) 
  5.     { 
  6.         //自定義初始化行為 
  7.     } 
  8.       
  9.      public override Task StartAsync(IPluginContext context) 
  10.      { 
  11.          //自定義啟動(dòng)行為 
  12.          return base.StartAsync(context); 
  13.      } 
  14.  
  15.      public override Task StopAsync(IPluginContext context) 
  16.      { 
  17.          //自定義關(guān)閉行為 
  18.          return base.StopAsync(context); 
  19.      } 
  20.  } 

2.3. 插件通信機(jī)制

插件通信機(jī)制是一種通用概念。當(dāng)各插件間協(xié)同完成一個(gè)功能時(shí),彼此進(jìn)行協(xié)調(diào)互助的一種機(jī)制。交互的形式有很多種,一種是插件對(duì)外開(kāi)放自己的接口,接入到服務(wù)總線中供其他插件調(diào)用;一種是提供消息機(jī)制,插件之間通過(guò)發(fā)送消息進(jìn)行事件處理。

2.3.1 基于虛擬服務(wù)總線形式的通信機(jī)制

基于虛擬服務(wù)總線形式的通信機(jī)制,每個(gè)插件都有自己的開(kāi)放接口,這些接口會(huì)被注冊(cè)到虛擬服務(wù)總線上,其他插件通過(guò)虛擬服務(wù)總線,獲取到其他插件的接口服務(wù)。此處涉及到的內(nèi)容是面向接口編程。

2.3.2 插件間消息通信

插件間消息通信屬于一種開(kāi)發(fā)人員可以自定義的擴(kuò)展方式,插件運(yùn)行主體無(wú)法定義所有的消息類型及消息的處理方法。所以用戶可以通過(guò)約定消息形式以及自定義消息響應(yīng)函數(shù),實(shí)現(xiàn)插件間的通信。但是這樣其實(shí)增強(qiáng)了插件之間的耦合度,不是特別推薦。筆者建議應(yīng)用層插件盡量只依賴通用服務(wù)型插件及主體運(yùn)行程序,業(yè)務(wù)插件保持獨(dú)立。

3. C++語(yǔ)言下的插件開(kāi)發(fā)案例

筆者曾基于某國(guó)外通用產(chǎn)品,進(jìn)行領(lǐng)域化定制。該產(chǎn)品基于C++/MFC開(kāi)發(fā),并提供SDK包和樣例工程,輔助用戶基于該產(chǎn)品的插件開(kāi)發(fā)。每個(gè)插件最終會(huì)編譯為一個(gè)DLL,拷貝到產(chǎn)品指定目錄下,就會(huì)被加載并執(zhí)行。整體模式如下圖所示。

  • 支持插件注入接口

通過(guò)繼承插件中指定的基類并實(shí)現(xiàn)指定接口,達(dá)到插件注冊(cè)及初始化的效果。

  • 支持用于注入菜單及子菜單的接口

通過(guò)菜單注入接口,開(kāi)發(fā)人員可以在菜單中提供插件功能入口。用戶可以通過(guò)該入口啟用該插件。

  • 支持事件分發(fā)(已定義標(biāo)準(zhǔn)事件清單),插件可以接收事件,并開(kāi)發(fā)自定義的事件處理程序

用戶在實(shí)際設(shè)計(jì)過(guò)程中針對(duì)模型、針對(duì)工程目錄、針對(duì)繪圖區(qū)域的操作,會(huì)分發(fā)到所有的插件中,類似于廣播。開(kāi)發(fā)人員根據(jù)實(shí)際需要去實(shí)現(xiàn)或者不實(shí)現(xiàn)。

  • 提供接口,獲取當(dāng)前上下文信息

提供訪問(wèn)接口,用戶獲取用戶當(dāng)前選中的模型對(duì)象、選中的目錄、選中的文件等信息。

  • 提供接口,用于所有業(yè)務(wù)對(duì)象的訪問(wèn)

提供訪問(wèn)接口,可以去創(chuàng)建、刪除模型,創(chuàng)建、刪除文件,創(chuàng)建刪除工程管理目錄等文件。

  • 插件以DLL的形式存在,進(jìn)程內(nèi)加載運(yùn)行

4. JAVA體系下的插件開(kāi)發(fā)案例

校園時(shí)代曾和同學(xué)一起開(kāi)發(fā)過(guò)一款桌面端設(shè)計(jì)軟件,就是基于Eclipse的RCP技術(shù)?;诓寮募軜?gòu)、擴(kuò)展點(diǎn)等概念,依舊印象深刻。其中開(kāi)發(fā)的基石Eclipse,就是基于OSGI規(guī)范進(jìn)行開(kāi)發(fā)。

4.1 OSGI簡(jiǎn)介

OSGi是基于java語(yǔ)言實(shí)現(xiàn)的開(kāi)發(fā)期和運(yùn)行期模塊化技術(shù)。它的核心部分是一個(gè)框架,其中定義了應(yīng)用程序的生命周期模式和服務(wù)注冊(cè)。OSGI框架定義了大量的OSGI通用服務(wù):日志、配置管理,XML解析等通用服務(wù)。

4.2 OSGI整體架構(gòu)

4.2.1 模塊層

模塊層可以理解為開(kāi)發(fā)出來(lái)的各類插件,一般以bundle的形式出現(xiàn)。一個(gè)完整的系統(tǒng)功能,往往由不同的模塊插件進(jìn)行配合完成。模塊之間通過(guò)約定好的接口為外部提供服務(wù)。也確定了每個(gè)模塊的邊界,并進(jìn)行封裝。

模塊層中bundle的特點(diǎn):

  • bundle 以 jar 包形式存在的模塊化物理單元,包含了代碼,資源文件和元數(shù)據(jù)(模塊描述信息)。
  • bundle 是開(kāi)發(fā)、部署 OSGi 應(yīng)用的基本單元。
  • bundle 的核心是 META-NF 目錄下的 MANIFEST.MF 文件。
  • bundle 定義了內(nèi)部包的對(duì)外可見(jiàn)性。
  • 每個(gè) bundle 都有單獨(dú)的類加載器。

4.2.2 生命周期層

管理bundle的創(chuàng)建,銷毀。Bundle內(nèi)部需要實(shí)現(xiàn)相關(guān)的接口,配合生命周期層的工作。

4.3.3 服務(wù)層

服務(wù)層可以理解為一個(gè)服務(wù)中心,每個(gè)插件將自己可以對(duì)外提供的功能通過(guò)服務(wù)層進(jìn)行發(fā)布,并給其他插件提供了服務(wù)發(fā)現(xiàn)的方式及服務(wù)訪問(wèn)。

4.3 Eclipse插件示例

Eclipse插件示例,采用Eclipse中自帶的Hello World案例進(jìn)行說(shuō)明。

插件的配置信息如下:

  1. Manifest-Version: 1.0 
  2. Bundle-ManifestVersion: 2 
  3. Bundle-Name: PluginDemo 
  4. Bundle-SymbolicName: PluginDemo 
  5. Bundle-Version: 1.0.0.qualifier 
  6. Bundle-Activator: plugindemo.Activator 
  7. Bundle-RequiredExecutionEnvironment: JavaSE-16 
  8. Automatic-Module-Name: PluginDemo 
  9. Import-Package: org.osgi.framework;version="1.3.0" 
  10. Bundle-ActivationPolicy: lazy 

一個(gè)簡(jiǎn)單的插件示例代碼如下:

  1. package plugindemo; 
  2.  
  3. import org.osgi.framework.BundleActivator; 
  4. import org.osgi.framework.BundleContext; 
  5.  
  6. public class Activator implements BundleActivator { 
  7.  
  8.   @Override 
  9.   public void start(BundleContext context) throws Exception { 
  10.     System.out.println("Hello World!!"); 
  11.   } 
  12.    
  13.   @Override 
  14.   public void stop(BundleContext context) throws Exception { 
  15.     System.out.println("Goodbye World!!"); 
  16.   } 

采用Eclipse OSGI模式進(jìn)行運(yùn)行,結(jié)果輸入如下。

  1. WARNING: Using incubator modules: jdk.incubator.vector, jdk.incubator.foreign 
  2. Hello World!! 
  3. 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
  4. !SESSION 2021-08-31 22:47:57.492 ----------------------------------------------- 

5. 總結(jié)

 

本文簡(jiǎn)單說(shuō)明了插件開(kāi)發(fā)架構(gòu)中的一些基本原則,以及采用不同語(yǔ)言開(kāi)發(fā)的軟件平臺(tái)中的插件開(kāi)發(fā)模式。需要注意的是,實(shí)際插件架構(gòu)中,根據(jù)產(chǎn)品的不同、面向的領(lǐng)域不同、采用的編程語(yǔ)言不同,會(huì)有很多不一樣的設(shè)計(jì),需要結(jié)合具體情況進(jìn)行設(shè)計(jì)。

 

責(zé)任編輯:武曉燕 來(lái)源: 一個(gè)程序員的修煉之路
相關(guān)推薦

2011-06-03 10:15:13

2018-04-19 10:46:39

3N層框架

2016-10-07 23:23:34

2021-07-30 13:46:59

前端架構(gòu)插件

2020-10-30 07:47:42

分布式

2009-06-04 20:26:45

2025-04-25 04:00:00

低代碼組件化元數(shù)據(jù)架構(gòu)

2013-04-15 16:56:48

微信公眾平臺(tái)Android開(kāi)發(fā)

2025-03-20 14:30:02

2023-08-20 12:37:44

前端開(kāi)發(fā)

2019-01-31 09:33:50

CNN神經(jīng)網(wǎng)絡(luò)激活函數(shù)

2012-05-28 09:50:32

jQuery插件

2009-06-03 16:06:28

Eclipse插件開(kāi)發(fā)Eclipse

2012-07-02 14:47:57

架構(gòu)敏捷開(kāi)發(fā)

2009-06-12 16:07:05

演進(jìn)式架構(gòu)設(shè)計(jì)敏捷開(kāi)發(fā)

2023-09-11 12:04:20

2012-06-13 10:17:40

jQuery

2011-08-29 14:50:08

jQuery插件

2022-08-02 08:01:09

開(kāi)發(fā)插件Chrome前端技術(shù)

2011-08-25 09:30:22

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)