You are on page 1of 42

插件架构及模式应


Plug-in Architecture

钟继坤
博客: http://blog.csdn.net/donjikn
邮件: mailto:donjikn@126.com
2006-07-21
内容包括:
 1. 插件架构 ( 对插件式应用程序的描述 )
 2. 相关模式 ( 对插件所应用的相关架构和设计模式 )
 3. 实例演练 ( 用简单实例来演示插件的实现 )
 4. 产品应用 ( 举例说明应用插件架构的现有产品 )

 5. 相关图书
1. 插件架构 ( 对插件式应用程序的描述 )

 插件 (plug-in 、 add-in 、 bundle)


 在不改变主程序的情况下,对主程序的功能进行
扩展;
 在保持接口不变的情况下,独立升级主程序和插
件程序,方便团队开发;
 形成产品线,提高开发效率,节省时间,快速推
出新版本,减少历史项目状态的维护;
 通用即插即用 (UPnP, Universal Plug&Play)
 像开发 USB 硬件产品一样开发软件产品;
1.1 插件架构图

应用插件
接口

主程序 核心插件
接口

插件调用 插件 SDK

基础库 ( 界面库、安全库、 XML 处理库等 )


1.1 插件架构功能

 插件的定义;
 插件的加载 ( 文件、 URL 等形式 ) ;
 插件的生命周期管理 ( 安装、卸载、启动、停止、更新 ) ;
 插件间的交互机制;
 插件的扩展;
两种典型的插件架构产品

 平扩展 微核 + 扩展
2. 相关模式 ( 插件应用的相关架构和设计
模式 )

 基本要素
 模式名称、问题、解决方案和效果
 常见代码中标识名称
 后缀 :
 …Factory, Builder, Creator, Singleton, Adapter, Impl,
Container, Façade, Wrapper, Proxy, Handler, Command,
Context, Interpreter, Expression, Iterator, Mediator, Token,
Observer, Strategy, Visitor, Driver
 函数:
 Create(), Clone(), …Instance(), Execute(), Action(),
Undo(), Redo(), Attach(), Detach(), Update(), Notify(),
Publish(), Subscribe()
2.1 GoF 模式分类:
创建型 结构型 行为型
目的
范围
类 Factory Method Adapter( 类方式 ) Interpreter
Template Method
对象 Abstract Factory Adapter( 对象方式 Chain of Responsibility
Builder ) Command
Prototype Bridge Iterator
Singleton Composite Mediator
Decorator Memento
Facade Observer
Flyweight State
Proxy Strategy
Visitor
2.2 模式的组织 ( 图 )

创建型 结构 型 行为型
目的
范围
类 将对象的部分创 使用继承来组合 使用继承来描述算法
建工作延迟到子 类 和控制流

对象 将对象的部分创 描述对象的组装 描述一组对象怎样协
建工作延迟另一 方式 作完成单个对象所无
个对象 法完成的任务
2.2 模式分类 ( 准则 )
 目的准则 ( 用于完成什么工作 )
创建型 结构 型 行为型
与对象的创建有关 处理类或对象的组合 对类或对象怎样交互和怎样
分配责任进行描述

 范围准则 ( 指定模式用于类还是对象 )
类 处理类和子类间的关系。静态的,在编译时已确定。
( 集中于处理类间的关系 )
对象 处理对象间的关系。动态的,运行时可变化。
( 大部分模式都属于对象模式 )
2.2 可复用设计的原则

 针对 接口 编程, 而不 是针对 实现 编程;


 客户无须知道他们使用的对象的特定类型,只须
对象有所期望的接口;
 客户无须知道他们使用的对象是用什么类来实现
的,只须要定义接口的抽象类;
 接口用于实现逻辑,具体类实现功能;
 优先 使用 对象组 合, 而不是 类继 承;
 委托 (delegate)
 类型参数化 (C++ 的 template<>)
 设计应支持变化;
2.3 插件架构相关的设计模式

 1. 工厂方法 (Factory Method)


 2. 单件 (Singleton)
 3. 桥接 (Bridge)
 4. 观察者 (Observer)
 5. 策略 (Strategy)
 6. 模板方法 (Template Method)
2.3.1 工厂方法 (Factory Method)

意图 :
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
Factory Method 使一个类的实例化延迟到其子类。
注: 由 Template Method 调用。
插件架构:插件管理器在不同平台的不同实现方法。 ( 比如对动态
库的调用: Windows : LoadLibrary() ; Unix-like : dlopen())
2.3.2 单件 (Singleton)

意图 :
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
衍生: 控制实例个数的 Singleton 。
插件架构:保证插件唯一实例。
2.3.3 桥接 (Bridge)

意图 :
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
插件架构:主程序和插件在接口不变的情况下独立升级。
2.3.4 观察者 (Observer)

意图 :
定义对象间的一种一对多的依赖关系 , 当一个对象的状态发生
改变时 , 所有依赖于它的对象都得到通知并被自动更新。
插件架构:对插件进行统一的管理和刷新。
2.3.5 策略 (Strategy)

意图 :
定义一系列的算法 , 把它们一个个封装起来 , 并且使它们可相
互替换。本模式使得算法可独立于使用它的客户而变化。
插件架构:同类插件的切换 ( 比如开发环境的版本控制插件 ) ,见
下页。
Visual Studio 的版本控制插件的切换
2.3.6 模板方法 (Template Method)

意图 :
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
Template Method 使得子类可以不改变一个算法的结构即可重
定义该算法的某些特定步骤。
插件架构:主程序在不同平台用相同的接口来管理和操作插件。
3. 实例演练 ( 用简单实例来演示插件的实现 )

 下面用一个基于插件架构的例子来演示。
 一个可扩展的实用工具。主程序提供界面框架,
插件扩展具体的功能,比如大小写转换等。
 组成:
 ① 主程序
 ② 扩展接口
 ③ 插件 SDK( 管理器、信息、参数类等 )
 ④ 插件实现
① 主程序
为插件提供可扩展的容器和操作方式。
② 扩展接口

 /// 初始化
 typedef bool (*SPL_INIT_FUNC)(const slcPluginArgs*);

 /// 运行
 typedef bool (*SPL_RUN_FUNC) (const slcPluginArgs*);

 /// 关闭
 typedef bool (*SPL_SHUTDOWN_FUNC) (const slcPluginArgs*);

 /// 获取插件基本信息
 typedef slcPluginInfo* (*SPL_INFO_FUNC)(void);
③ 插件 SDK ( 插件管理器类 )
 负责插件的搜索、加载、管理、运行、刷新和缷载等。
 slaPluginServer ( 抽象 )
 GetLoadedPlugins (…)
 GetSafedPluginInfo (…)
 GetPluginInfo (…)
 GetAllPluginInfos (…)
 LoadAllPlugins (…)
 LoadPlugin (…)
 UnloadPlugin (…)
 UnloadAllPlugins (…)
 RunPlugin (…)
 RunAllPlugins (…)
 Refresh (…)
 slcPluginServer ( 针对 Win32 或 Linux 平台下的具体实现 )
③ 插件 SDK ( 插件信息类 )
 描述插件的基本信息 (Id 、参数、作者、描述、联系方式、版
本等 ) 。
 slcPluginInfo
 Clear
 GetArgCount
 GetArgDescription
 GetArgName
 GetName
 GetVendor
 GetInfo
 GetDescription
 GetHomepage
 GetEmail
 GetMajorVersion
 GetMinorVersion
 GetBuildVersion
 GetUUID
 HasPublicArgs
③ 插件 SDK ( 插件参数类 )

 封装主程序和插件之间的交互参数。
 slcPluginArgs
④ 插件实现

 在具体的插件库内实现扩展接口 。
 bool splInitialize(slcPluginArgs* a_pPluginArgs);
 bool splRun(slcPluginArgs* a_pPluginArgs);
 bool splShutdown(slcPluginArgs* a_pPluginArgs);
 slcPluginInfo* splGetInfo(void);
4. 产品应用 ( 举例说明应用插件架构的产
品)

 1. 基于 C++
 Linux Driver 、 Code::Blocks 、 Adobe Photoshop 、 Winamp 、
 CodeWarrior
 2. 基于 Microsoft COM
 Visual Studio 、 Internet Explorer 、 Microsoft Office 、 Media
Player 、 Windows MMC 、 WPS Office
 腾讯 QQ 、腾讯 RTX
 ArcGIS 、 SuperMap
 3. 基于 .NET 或 Mono
 SharpDevelop 、 MonoDevelop
 4. 基于 Java
 IBM Websphere 、 Eclipse (OSGi Framework)
 Sun NetBeans
 …
Visual Studio
扩展接 口: IDTExtensibility2
The add-in event sequence
Eclipse
Eclipse Platform
Bundle 状态转换
文本编 辑相 关的插 件
Eclipse 家规 ( 扩展者 )
 贡献法则:一切皆是贡献;
 遵循法则:插件必须遵循预期的接口;
 共享法则:增加,不要取代;
 有样学样法则:遇到问题时,首先复制类似插件的结构;
 相关性法则:只有在操作有可能成功时才显示你所贡献的操作;
 整合法则:要整合,不要分裂;
 责任法则:明确指出你开发的插件是问题的源头;
 针对 API 契约编程法则:首先检查 Eclipse API 契约,然后针对契约编
程;
 “ 其他”法则:让用户可能选择所有东西,但把那些通常不用于当前
视角的选项放在“其他…”对话框中;
 Iresource 适配法则:应该尽量为领域对象定义 Iresource 适配器;
 分层法则:将语言无关的功能与特定于具体语言的功能分开,将核心
功能 (core) 与用户界面 (ui) 功能分开;
 使用连贯性法则:在多次会话之间,应该保持用户界面状态一致;
Eclipse 家规 ( 促成者 )
 邀请法则:尽可能地邀请别人为你的作品作出贡献;
 懒加载法则:只有在真正需要的时候才加载插件;
 安全平台法则:作为扩展点的白日提供者,你必须保护好自己,不要
让扩展者的误操作给你造成损失;
 公平竞赛法则:所有使用者遵守同样的游戏规则,包括我自己;
 明确扩展法则:明确说明平台的什么地方扩展;
 发散性法则:一个扩展点接纳多个扩展;
 良好防御法则:如果要交出程序的控制权,首先保护好你自己;
 用户决定法则:如果有多个选择,由用户决定使用哪一个;
 明确 API 法则:将 API 与插件内部使用的类分开;
 稳定性法则:如果你已经开始邀请其他人作出贡献,就不要再改变游
戏规则;
 保守 API 法则:只暴露你有信心的 API ,但同时也应该做好准备暴露
更多的 API ,因为使用者会要求你这样做。
Eclipse 家规 ( 发布者 )

 许可法则:每项贡献品都 应该提供许可证;
Eclipse 插件集

 官方网站: www.eclipse.org
 OSGi Framework ( 标准化的核心框架 )
 RCP ( 丰富客户平台 )
 PDE ( 插件开发环境 )
 JDT (Java 开发工具 )
 CDT (C/C++ 开发工具 )
 WDT ( 网页开发工具 )
 UML2 (UML2.0 建模工具 )
 …
Eclipse 动态

 ( 准 ) 采用 Eclipse 作为基础平台的公司:
 IBM 的全线产品
 Websphere
 Rational
 Lotus
 Borland JBuilder
 WindRiver Workbench
 TI CCS
 BEA Workshop Studio
 Eclipse 不只是一个平台,而是开源经济效应

5. 相关图书
 《设计模式》 (GoF)
 《重构》
 《过程模式 ( 上、下 ) 》
 《 C++ 设计新思维》
 《 C++ Template 中文版》
 《 Contributing to Eclipse 中文版》 (Erich Gamma 等 )
 《面向模式的软件体系结构 ( 卷 1 、卷 2 和卷 3) 》
 《 C# 项目开发全程剖析》
 《 ACE 程序员编程指南》…
 《 UML 与模式应用 (3rd) 》
 《软件配置管理中的模式与反模式》
 《企业应用架构模式》
 《软件架构:组织原则与模式》
插件架构

谢 谢 ! ^_^

博客:
http://blog.csdn.net/donjik
n
邮件:
mailto:donjikn@126.com

You might also like