Professional Documents
Culture Documents
用
Plug-in Architecture
钟继坤
博客: http://blog.csdn.net/donjikn
邮件: mailto:donjikn@126.com
2006-07-21
内容包括:
1. 插件架构 ( 对插件式应用程序的描述 )
2. 相关模式 ( 对插件所应用的相关架构和设计模式 )
3. 实例演练 ( 用简单实例来演示插件的实现 )
4. 产品应用 ( 举例说明应用插件架构的现有产品 )
5. 相关图书
1. 插件架构 ( 对插件式应用程序的描述 )
应用插件
接口
主程序 核心插件
接口
插件调用 插件 SDK
插件的定义;
插件的加载 ( 文件、 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 可复用设计的原则
意图 :
定义一个用于创建对象的接口,让子类决定实例化哪一个类。
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