- 浏览: 508987 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
michao:
大哥,还有aperture.exe吗? 发我一份,找不到呀,m ...
使用aperture框架让AS3与C++通信,执行本地代码 -
Aaron-Joe-William:
文件被删除了。下不了。
SQLite 数据库加密的一种解决方案 -
hanmiao:
樓主的文章不就是來自IBM Developers里的http: ...
mina 入门 -
howesen:
断包与粘包问题,需要处理下就好了
mina接收数据不全(2) -
sniciq:
git clone --recursive git://git ...
ESB学习笔记(Spring Integration实战)
当一个软件项目开发结束并交付使用后,假如需要增加一些新的功能时,我们希望在不修改原有的应用程序情况下,将新增加的功能"插入"到系统中,这就是所谓的插件化,而新增加的功能模块就叫插件。
插件化技术并不是新的技术,早期很多基于COM的开发的Win32应用程序都是插件化
的系统,IE浏览器就是一个典型。而IE浏览器下各种工具栏,如google或yahoo等搜索栏就是插件了。再举个例子,开发工具eclipse。
eclipse最大的魅力在于无限的功能扩展, 很多第三方的厂商都以产品的形式推出实现各种的插件来实现特殊的功能。
插件化系统较传统的软件具有以下的特点:
易于维护
易于维护体现在对插件功能的维护。
当一个系统功能修改或发现Bug, 希望更新最小粒度的模块。 一是解决维护的成本, 二是将修改后的功能对其它完整功能带来的影响降到最低。 在插件化系统中插件一般体现为独立的dll, 这就使得开发人员修改功能时只重新编译相关得dll即可。
易于团队开发
大多数程序员应聘的简历中一般都会有 "良好的团队沟通和协作的能力", 由此可见团队开发中对个人的沟通和协调能力要求的重要性, "沟通协作"的好坏直接影响产品的质量, 那么反过来我们也可以认为: 降低或减少团队中个人之间的沟通和协作势必提高软件产品的质量。。
A和B图分别代表了普通模块划分和插件化模块划分的开发结构,图中箭头代表模块之间的依赖方向,即存在着“沟通和协作”关系。A中,模块之间可能存在较复杂的关系,而B中,各插件模块之间没有依赖关系的,它们只与主框架模块(下面介绍主框架模块)发生关系。
易于功能扩展
任何软件产品都是有生命周期的,
作为程序的创造者,大家都不愿意看到其消亡的现实。 因此应当尽量延长软件产品的生命周期, 不断的将新的功能注入到现有的软件产品是一个手段。
插件化的系统架构为扩展新功能提供了更好的方便性。因为新的功能以插件的形式给出时,是相对独立的,不影响整个系统框架和其它的功能。
甚至是把扩展软件功能的能力提供给用户或第三方厂商,以达到最大限度的功能扩展。
实现插件化的技术支撑
在此之前来探讨一下插件化技术的雏形。 这就必须从库的发展谈起。 库做为独立的功能模块从可执行应用程序分离出来经历了 静态库 和动态库两个阶段,
动态库又随着面向对象技术的发展从用于包装函数到封装类。
如果了解Windows下计算机病毒技术, 可以知道,早期很多病毒制造者依靠系统一个叫
rundll32。exe进程来启动自己的包含破坏行为代码的动态库,来达到病毒在系统中隐藏运行的目的。
而这个rundll32。exe所运行的dll库是包装函数的,只要病毒DLL文件遵循相关的函数名或参数名规则就能被加载和调用。
笔者认为类似这种规定动态库入口函数或者参数名方式来扩充系统功能的技术就是插件化系统的雏形。 在这种情况下, 病毒库可以理解为插件。
COM体系盛行后, 插件技术得到了较成熟的支持, 可以说插件化是COM技术的重要特点之一。
但是受COM自身一些底层实现方式的限制(比如类注册方式,安全机制, 以及臭名昭著的DLL地狱等),
使得在COM平台下开发插件化系统相当的繁琐并且对开发人员的技术水平要求较高。
随着计算机编程语言的发展, 当今流行的Java和C#语言等都提供了新的特性来更方便地支持插件化的系统实现, 在C#中主要依靠接口和类的反射机制两种技术:接口和反射。
接口
接口是插件行为的描述。 接口不包括任何业务逻辑实现,业务逻辑包含在实现接口的类中。
接口声明:
public
interface
IPlus
{
///
<summary>
///
插件行为方法
///
</summary>
void
DoSomething();
}
类的实现:
public
class
Plus1
: IPlus
{
#region
IPlus
成员
void
IPlus
.DoSomething()
{
MessageBox
.Show(GetType().ToString() + " Do somthing..."
);
}
#endregion
}
插件化系统中提倡通过接口的方式来访问对象,也可以使用虚基类来实现整个系统。使用接口和使用类,在业界也是经常引起争议的话题,笔者比较推荐用接口来实现。
反射
反射主要理解为在未能引用类的类型定义情况下创建和访问对象的能力。
名字空间Kaitu.System中包含了Form类。 一般情况下当需要创建一个Form类的对象时, 必须引用Kaitu.System命名空间, 然后声明Form类型的对象,然后用new操作创建对象。
Form frm = new Form(); //
一般类对象的创建。
假如Form类的定义暂时不能引用到当前的开发环境下 , 但时程序在运行期却是能创建并访问它, 这个时候就要利用反射机制来创建该对象:
比如:
using
System.Reflection;
//
加载运行期的程序集。
Assembly
SampleAssembly = Assembly
.LoadFile(@"c:\kaitulib.dll"
);
//
创建程序集中包含的类对象。
object
instance = SampleAssembly.CreateInstance("Guost.Lib.PlusA"
);
首先是通过程序集的文件名加载程序集对象,
这里类似设计期对程序集的引用。然后是通过类的名称字符串创建类对象,从这里可以看出,创建一个类对象不再用new的方式,而是通过程序集名称和类名字符
串创建的。
这里可能有人要问,既然不引用程序集,那么怎样访问创建后的对象呢?用接口,反射创建的类对象都实现了接口,而接口我们在应用程序设计期是可见的。
IPlus
myPlusObject = instance as
IPlus
; //
将对象转到接口
MyPlusObject.DoSomething(); //
调用业务逻辑
插件化系统基本组成
从上图中可以看出,插件化系统由三个主要部分构成:应用程序主框架,插件配置文档和各种插件。
应用程序主框架
应用程序主框架至少包含描述插件行为的接口定义和插件管理器两个部分。插件管理器包含
一个用于存储插件对象引用的列表,或者字典表。插件管理器负责以反射的方式将插件对象创建起来,并保存到插件列表中。并实现一种插件对象的检索和展现机
制,即通过应用程序UI部分将系统中已经加载的插件以控件形式展现给用户,(通常是工具栏按钮或菜单项),当用户操作这些控件时,插件管理器又负责快速地
检索相应地插件对象并调用其的业务逻辑。
插件配置文档
由于应用程序主框架加载各个插件时通过类反射机制创建对象,这就要求主框架必须
识别插件类所在程序集的名称字符串和类。插件配置文档用来存储这些信息。一般情况下当系统增加一个插件功能时,为了使应用程序主框架能够加载这个插件必须
在配置文档中对该插件的程序集名称和类名称加以描述。配置文档一般以XML格式存储,也可以根据指定插件程序集的存储路径方式来代替配置文件的形式。
以下是一个典型的应用程序主框架实现代码:
using
System;
using
System.Collections.Generic;
using
System.ComponentModel;
using
System.Data;
using
System.Drawing;
using
System.Text;
using
System.Windows.Forms;
using
System.IO;
using
System.Reflection;
namespace
MainFrame
{
///
<summary>
///
插件系统应用程序主框架
///
</summary>
public
partial
class
Form1
: Form
{
public
Form1()
{
InitializeComponent();
//
加载插件从当前应用程序目录下检索包含插件的程序集,然后加载。
string
plusPath =
System.Windows.Forms.Application
.StartupPath + @"\plus"
;
DirectoryInfo
plusDirInfo = new
DirectoryInfo
(plusPath);
FileInfo
[] fileInfos = plusDirInfo.GetFiles();
for
(int
i = 0; i < fileInfos.Length; i++)
{
if
(fileInfos[i].Extension.Equals(".dll"
))
{
Assembly
SampleAssembly;
try
{
SampleAssembly = Assembly
.LoadFile(fileInfos[i].FullName);
Type
[] objTypes = SampleAssembly.GetTypes();
for
(int
k = 0; k < objTypes.Length; k++)
{
Type
objType = objTypes[k];
object
plus = SampleAssembly.CreateInstance(
objType.ToString()); //
反射机制创建对象
plusList.Add(objType.ToString(), plus as
IPlus
);
//listBox1
的作用是向用户展现系统加载的插件。
this
.listBox1.Items.Add(objType.ToString());
}
}
catch
(Exception
ex)
{
MessageBox
.Show("
创建插件对象失败!
"
+ ex.Message);
}
}
}
}
///
<summary>
///
插件字典。
key
为插件的类名,
Value
是插件类对象实例
///
</summary>
private
IDictionary
<string
, IPlus
> plusList
= new
Dictionary
<string
, IPlus
>();
private
void
listBox1_Click(object
sender, EventArgs
e)
{
//
当用用户点击
listBox1
时,则根据用户点击的项来调用插件的业务逻辑方法。
string
key = listBox1.Items[this
.listBox1.SelectedIndex].ToString();
IPlus
plus = this
.plusList[key]; //
获取插件对象
plus.DoSomething(); //
调用插件对象业务逻辑方法
}
}
}
总结
任何开发技术都不可能是完美无缺的,插件化技术也不例外。插件化的系统无限的功能扩展性并不是绝对的,扩展的插件类必须符合插件接口的定义。而且接口的定义在系统版本升级时不允许修改的,这无疑加大了系统设计时接口的定义难度。
图表 1
插件化系统Demo程序运行界面。
发表评论
-
RichTextBox 添加控件,被禁用如何处理 button
2010-11-01 18:45 1291WPF中RichTextBox的确非 ... -
归纳一下:C#线程同步的几种方法
2010-10-28 11:18 1321我们在编程的时候,有时会使用多线程来解决问题, ... -
关于WPF ListView数据绑定 入门 及分类,排序
2010-09-03 18:14 9365不多说,先直接上代码 ... -
关于WPF 数据绑定简单介绍及入门
2010-09-02 20:07 5364今天搞了一下午的数据绑定,由于以前用FLEX的数据绑定很 ... -
回调函数原理
2010-08-10 12:04 2239回调函数原理 声明CALLBACK 调用(call ... -
C#制作屏幕保护的方法 函数
2010-08-10 10:16 1485本文介绍使用C#制作屏 ... -
初探C# 异常处理
2010-08-03 10:39 1326一、基础 在C# 里,异 ... -
C#中使用try catch对系统性能的影响和处理机制的学习总结!
2010-08-03 10:31 2846问题1:当一段代码被try ... -
C# WebClient上传下载时进度条显示,找了好久才找到的哦!
2010-07-23 11:05 77022、代码: using System; using Sys ... -
WinFrom通过WebClient上传下载文件(带进度条)
2010-07-23 10:48 4296(2009-09-27 12:18:09) 转 ... -
关于图片保存问题
2010-07-15 20:01 995如果你在用PngBitmapEncoder之类的 Save图片 ... -
Windows 7 任务栏开发 之 进度条(Progress Bar)
2010-07-12 14:33 1983上一篇 我们完成了“覆盖图标”(Overlay ... -
WPF 新弹出窗口抢焦点问题
2010-06-21 16:34 4116新弹出窗口抢了正在使用的窗口焦点,这个问题烦了好久,今天终于有 ... -
C# 第三方控件
2010-06-08 10:29 3059DevExpress,NetAdvantage 这两套算是最全 ... -
浅析C#中三层架构的实现
2010-06-02 16:14 1621本文讨论如何在C#中实现三层架构,使用MS Acces ... -
数据绑定
2010-05-31 18:42 860http://liutiemeng.blog.51cto.co ... -
C# 修改警告心得
2010-05-22 17:08 14231.(CA1031)如果有try catch最好不要捕获Exc ... -
C# log4net
2010-05-17 13:40 2208说明:本程序演示如何利用log4net记录程序日志信息。log ... -
C# 开机启动
2010-05-13 17:41 1654C# winform程序设置开机 ... -
Base64编码的字符串与图片的转换 C#
2010-04-28 15:05 2840using System; using System.Col ...
相关推荐
新浪微博何为舟-自动化策略生成的思考与实践.pdf
精细化管理模式的构成包括:管理者管理能力职业化、生产管理精细化、质量管理精细化、设备管理精细化、物料管理精细化、成本管理精细化、现场管理精细化等七个方面。这些方面是精细化管理的基础,旨在帮助企业建立...
【标题】: 何为基于伦理优势的竞争优势 在当今竞争激烈的商业环境中,伦理优势逐渐成为企业获得竞争优势的重要因素。本讲座将深入探讨如何将伦理优势转化为实际的竞争优势,主要涉及以下几个方面: 一、远大的企业...
规范化的企业管理制度是指企业为了提升运营效率、保证服务质量、促进可持续发展而建立的一套系统化、标准化的管理规则和流程。这套规则涵盖了企业的各个层面,包括组织架构、决策机制、人力资源管理、财务管理、市场...
机器视觉与人类视觉相比,有其独特的优势。例如,机器视觉可以在更短的时间内处理大量图像,精确度高,不受环境因素如疲劳、情绪等影响。这使得它在工业自动化、质量控制、医疗诊断、自动驾驶等领域具有广泛的应用。...
然而,对于何为嵌入式系统,以及什么样的技术能够被称为嵌入式技术,这一问题至今仍存在一定的争议。本文将深入探讨嵌入式系统的定义、特点及其核心技术。 #### 什么是嵌入式系统? 嵌入式系统是指专门设计用于...
数字化仓储项目应用方案是现代企业提升物流效率、降低运营成本的重要手段,尤其在智慧仓储与仓储...在实际应用中,企业应根据自身业务需求,合理选择和配置硬件设备,优化软件系统功能,以充分发挥数字化仓储的优势。
### 建筑设备自动化系统(BAS)在智能建筑中的应用 #### 一、智能建筑为何需要使用BAS? 在探讨智能建筑为何需要使用建筑设备自动化系统(BAS)之前,我们先简要回顾一下BAS的历史起源和发展背景。1883年,Warren S. ...
IT知识浅析(何为系统集成商).pdf
论何为教育.pdf
在探究国际化架构设计,特别是针对腾讯海外计费系统的架构演进时,首先要理解的是何为国际化架构设计。国际化架构设计是指在设计软件系统或服务时考虑不同国家和地区的特殊性,使得产品能够在全球范围内平滑运行,...
要深入理解数字化转型,首先要明确何为数字化。在字面上,数字化指的是将信息转化为数字信号,借助计算机技术进行处理。然而,这只是其基本层面的含义。 真正的数字化转型远不止于此,它是一种对企业业务流程的深度...
系统栈有何用途?用户栈有何用途? 答:系统栈是内存中操作系统空间的一个固定区域;用户栈是内存中用户空间的一个区域。系统栈的作用:(1)保存中断现场,对于嵌套中断,被中断程序的现场信息依次压入系统栈,中断...
### 何为HDMI?步入数字化需要知晓的点滴 #### HDMI概述 HDMI(High Definition Multimedia Interface,高清晰多媒体接口)是一种专为音频和视频信号传输设计的接口技术,被视为下一代音视频主流接口。它能够在...
标准化也有助于降低成本,并加快了产品上市的时间。 **3. 可扩展性与灵活性** RapidIO支持多种物理层技术和封装方式,如铜缆、光纤等,因此具有很好的可扩展性和灵活性。这意味着它可以适应不同的应用场景和技术...
30张PPT截图揭秘何为工业4.0
1. 理解何为企业信息化:明确信息化的目标是改进业务流程和组织结构,实现信息共享和协同工作。 2. 识别企业信息化要素:包括业务过程的数字化管理、信息系统的网络基础以及量化管理技术的运用。 3. 实施外贸企业...