当前位置:文档之家› 插件系统

插件系统

插件系统
插件系统

插件系统

插件系统框架分析

插件系统概述

普通的系统,在编译发布之后,系统就不允许进行更改或扩充了,如果要进行某个功能的扩充,则必须要修改代码重新编译发布。使用插件可以很好地解决这个问题。

插件概念

首先由开发人员编写系统框架,并预先定义好系统的扩展借口。插件由其他开发人员根据系统预定的接口编写的扩展功能,实际上就是系统的扩展功能模块。插件都是以一个独立文件的形式出现。

对于系统来说并不知道插件的具体功能,仅仅是为插件留下预定的接口,系统启动的时候根据插件的配置寻找插件,根据预定的接口把插件挂接到系统中。

优势

一、系统的扩展性大大地加强了。如果我们在系统发布后需要对系统进行扩充,就不必重新编译,只需要增加或修改插件就可以了。

二、有利于模块化的开发方式。我们可以开发强大的插件管理系统,在这样的一个插件系统下,我们可以不修改基本系统,仅仅使用插件就能构造出各种各样不同的系统。

Eclipse系统架构

Eclipse插件系统是非常成功的插件框架结构。网上有很多介绍的文章。这里推荐孟岩的Blog https://www.doczj.com/doc/3b18139471.html,/blog/archives/2005/09/08/67.html。下面对Eclipse的框架中的几点做一个简要的介绍,在后面介绍插件系统架构的时候作为对比。

插件结构

Eclipse是众多“可供插入的地方”(扩展点)和“可以插入的东西”(扩展)共同组成的集合体。在我们的生活中,电源接线板就是一种“扩展点”,很多“扩展”(也就是电线插头)可以插在它上面。(摘自《Contributing to Eclipse》Erich Gamma, Kent Beck著)

Eclipse整个IDE就是一个插件,他提供了新的扩展点供其他插件来扩展。

扩展点

可以看到Eclipse的插件结构是由父插件管理子插件,插件之间由扩展点连接,最终形成树形的结构。

界面呈现

界面呈现由提供扩展点的父插件来决定,比如说父插件在菜单上留了扩展点,那么子插件就可以出现在菜单项上。界面呈现的类型是由提供扩展的插件决定。

插件交互

插件之间的交互通过扩展点实现。父插件调用子插件实现的扩展点来触发子插件的动作。

依赖关系

配置文件中指定插件运行需要依赖的插件,在装载过程中会按照依赖的关系顺序来装载。

扩展点形成的系统结构

Eclipse中的插件用扩展点的机制连接起来,形成如下图所示的系统结构。插件必须实现扩展点,以此插入到系统中,新增扩展点并不是必须的,但只有新增了扩展点的插件才可以被别人扩展。

懒加载

只有在调用执行动作的时候才会将真实的动作对象创建起来。由于在配置文件中已经具备真实动作的一切信息,所以在不装载插件时,同样可以在父插件的界面上将扩展的功能显示出来。

另一个插件系统

插件结构

插件分为“插件外壳”和“业务”两部分。

其中业务部分与插件没有任何关系,按照一般的应用程序开发即可。最终提供给插件外壳一个主要的界面和公布出来的方法。

插件外壳提供接口供外界调用。系统和其它插件完全通过插件外壳和插件进行交互。

界面呈现

将每个插件的界面按照一定形式组织起来生成整个系统。界面组织的规则在配置文件中指定。系统提供可配置的方案。

布局(Layout)

插件按照一定的布局放到整个系统的界面中。在目前的系统内提供了三种布局。

页面布局

将插件按照页面的形式重叠在一起,插件激活时将自己所属的页面翻转到最前端。

模块布局

将插件按照模块划分放到同一个界面显示。模块之间用分割条连接。

页签布局

将插件按照页签的形式放到一起。

装饰(Decorator)

布局指定了插件出现的位置与形式。装饰可以指定插件出现的方式。

可关闭装饰

指定插件出现的部分是否可以关闭。在普通的模式下,插件可以按照上面的几种版型出现,但这时的插件界面是不可关闭的。如果需要增加关闭功能,可以给插件指定一个装饰器。

下面举一个在模块布局中的模块2上应用“可关闭装饰”的例子。

布局、装饰的组合

上面列举了现有的布局与装饰,复杂界面同样可以有布局与装饰的组合来完成。这里的图式表明将三种布局与装饰组合的一种情况。

通过配置文件指定出不同的组合情况就可以完成更多的界面布局了。在更改整个系统界面布局的时候只需要修改配置文件,程序并不需要重新发布。

导航

通过配置文件装配好的插件系统,界面可能是非常复杂的。这种情况下要让用户找到想要的功能需要用导航器来呈现系统提供的所用功能。

系统提供的功能就是插件提供的功能的集合,插件提供的功能通过插件外壳公布出来。公布的方式依照语言的特性来定:C#、Java中可以利用反射机制运行公布出来的方法,Delphi中用RTTI也可以同样运行配置文件中指定的方法。

常见的导航器都可以抽象成树形结构。每一个导航单元映射到一个用户需要的功能,每一个功能对应到具体的插件的某一个方法。将功能抽象成一个Action对象,对象需要知道它导向的插件和方法名。

可以在上面抽象模型的基础上实现任意形式的导航器。可以是菜单项,可以是TreeView,也可以是自定义的控件。

交互关系

系统需要知道插件的操作,插件与插件之间同样也会有交互。

将所有的交互关系用一个关系管理器来存储,插件与外界交互都通过关系管理器来实现。关系是在配置文件中指定,分析配置文件的时候就会将配置中指定的关系注册到关系管理器中。

在运行期,插件动态从关系管理器中取得和自己关联的接口。

懒加载

为了节省用户资源,需要实现插件的按需加载,也叫懒加载,只有用到的插件才会从文件中装载到内存中运行。

实现懒加载需要处理导航器和插件的布局。很多地方需要绑定插件的信息,但这时插件对象还不存在。使用代理插件可以解决这个问题。

所有与插件的通信都通过代理插件对象来中转。代理对象由主框架创建,记录插件的基本信息。在系统装载期,绑定到系统中的接口都是代理对象,当外界需要与插件交互,例如显示、运行某个方法的时候,由代理来自动装载真实的插件,然后将调用委派给插件来响应。这样可以让懒加载过程对于系统装载,插件运行是透明的。

架构对比

微内核 VS 巨内核

Eclipse中的运行框架非常小,系统中几乎所有的都是插件,采用的是微内核+插件的形式。在后面介绍的插件架构中系统运行框架比较复杂,它包括了界面布局策略、导航、插件代理等职责,可以说是巨内核+插件的形式。

微内核与巨内核之争已经有很长历史了。在操作系统的概念中尤为突出。网上对于微内核与巨内核的讨论同样适用于插件系统。

仅从上面介绍的两种插件系统来看,微内核的好处在于系统的可扩展性强,如果你愿意,甚至可以将Eclipse 整个开发环境都替换掉;巨内核的好处在于插件非常简单,只需要将业务部分用统一的接口公布出来就可以,在开发具体模块的时候可以不用考虑开发的是否是插件。

界面呈现

微内核中的界面呈现完全由父插件来决定,留了什么样的扩展点就可以在界面上以什么样的形式发布功能。

巨内核中的界面呈现由系统运行框架决定,框架支持了几种显示的模式。配置文件可以在现有的模式之上随意组合形成复杂的界面。在这个过程中插件并不关心自己被放在什么地方,或者以什么形式呈现。

插件关系

微内核中的插件关系由插件自身来维持,插件实现的扩展决定了它和父插件之间的交互关系,新增的扩展点决定了它和将来在它基础上扩展的插件交互的模式。

巨内核中的插件关系由系统框架(关系管理器)统一管理,插件本身不需要维护交互信息,只有在需要的时候才会从关系管理器取得。

懒加载

两种架构都可以支持插件的懒加载。基本的思路是一致的。但微内核中的插件装载由父插件来完成,而巨内核中的装载则直接由系统框架提供的统一代理类来完成。

配置还是派生

在插件系统中,每一个插件都有自己的一些配置信息,比如说图标信息、界面显示信息等。如果以前做了

一个插件,发现另外一个插件和它的功能差不多的时候该怎么办呢?可以用配置文件将不同的地方描述出来,也可以在以前的基础上做一个派生类。到底是用配置还是用派生,这个问题就有趣了。

都是变化惹得祸

中国特色的软件产品就是地区版本多,同样一件事情每个地方规则都不一样。比如说做了一个功能,在北京用没有问题,拿到上海去就不符合要求了。地区特性要求我们的软件必须要响应变化。

出现变化后的第一个反应就是OO了。有着各式各样的设计模式来教我们怎样利用OO的特性来应对变化。比如说现在需要一个计算个人所得税的模块。

计算的思路都是一样的,但由于地区经济的差异,所以在有些数据上各个地方会略有不同。

按照OO的思想来考虑,我们可以做一个计算的基类,利用模板方法将各地不同的地方做成虚函数。基类中处理具体计算的算法,派生类中处理地区差异,比如说各地的税收起征额不同。在到具体地区实施时只需要选择不同的派生类就可以了。并且也非常方便扩展。如下面的TaxCalculator1。

同时也有另外一种思路,在TaxCalculator2中没有什么虚函数,也不存在派生类,不过它运行的时候需要一个配置文件,在配置文件中描述地区差异。

当然,这里说的是一种非常简单的情况,在实际的应用中比这个要复杂的多。

就上面分析的来看,似乎用派生和配置两种方案都可以。如果是OO思想的“崇拜者”很可能觉得第一种方法更好,因为第二种方法不是面向对象的思路。

考虑成本

在项目中遇到这个问题时,是和插件机制联系起来的。也就是说插件之间从逻辑上讲是“派生”的关系(一个插件为一个DLL文件)。如果按照类派生的方式来处理,则需要将不同的派生类分别编译成不同的DLL 发布出去;如果用配置文件则只需要发布一个DLL文件另外附加上不同的配置文件。

从插件发布的角度考虑,用配置文件的代价要更小。所以在实际的项目中,采用第二种方式居多。并且在非插件系统中用派生方式实现的模块也尽量考虑用配置文件的方案。

其实在这里我考虑的最主要的因素是“成本”,分为下面两个部分。

维护成本

用派生的方式实现,在维护期间需要维护的是代码;用配置文件的方式实现,在维护期间代码不需要维护,只需要改变配置就可以满足要求。我们认为维护代码的成本比维护配置的成本要高。

发布成本

用派生实现,需要发布给用户多个DLL文件;用配置文件实现,需要发布给用户一个DLL文件,多个配置文件。我们认为发布DLL的成本比发布配置文件的成本要高。

结合上面的成本因素来考虑,用配置文件的成本要低,所以选择这种方式。

产品是二进制文件

我们的产品是什么?以前很直观的认为程序员的产品就是代码。

代码和设计文档、计划文档一样都不是最终产品,它们都属于文档的范畴。最终生成产品的不是我们程序员,而是编译器。代码是一种文档,编译后生成的二进制文件才是产品。

在项目中,我们会考虑从设计文档到代码需要的成本,但极少考虑从代码到二进制需要的成本。原因很简单,因为从代码到二进制的过程太廉价了。通常我们不需要考虑编译过程的成本因素。

由此来看,上面提到的“发布成本”是可以忽略不计的。

动态语言的优势

关于维护成本这一点,就是仁者见仁,智者见智了。

有的人就喜欢读代码:) 所以很难说维护代码和维护配置文件那一个成本高了。不过有一点没有争议,那就是到了用户那边,二进制文件可是没有办法改的了。

有些喜欢刨根究底的人就会进一步钻牛角尖,就像我一样。

如果用动态语言又会是什么样的情况呢?

因为动态语言不需要编译成二进制文件,所以它就是一种可以运行的文档了。可以将我们系统中的配置文件当作动态语言的一种,不过它只能决定简单的行为。因为配置文件毕竟不支持“封装”、“继承”和“多态”。用真的动态语言的话,既可以得到配置文件灵活的优势,又可以得到编程语言强大的功能。

从这点来看,动态语言在这个场合还是非常有用的。

系统中的插件和控件

插件可以封装一定的业务,同样控件也具有封装性。

可以说控件的出现大大简化了我们开发的工作量。作为一个插件系统来说,实现一个通用的插件能在更大粒度上进行复用。插件是比控件更加高层的一种模块封装方式。

插件和控件有相同的地方:封装和复用。本文分析了它们的异同,并且提出另外一个比较有趣的概念——伪插件。请大家继续往下读一读。

一、插件和控件的比较

发布

控件编译到系统中,和系统作为一个整体发布。

插件是在系统的运行过程中动态关联到系统上,可以和系统的其他部分保持物理上的隔离。

配置能力

控件在系统中的呈现方式在编译时已经确定,通过代码描述控件的表现形式,呈现位置等。

插件的呈现方式在运行的时候根据外部的配置文件指定。

功用

控件作为公用的组件使用,在我们编写业务模块时,控件作为基本资源被我们使用。

插件作为一个独立的业务模块存在,直接面向用户。

开发调试

控件的调试简单,但插件的调试却比较麻烦。正是因为为了灵活性而制造的隔离措施导致了调试上的困难。通常一个插件作为一个工程开发。

二、插件与控件的关系

插件是业务模块,就像上面所说的,在我们编写业务模块时控件作为基本资源被使用。所以插件与控件的关系如下图左所示,普通的业务模块如下图右所示。

可以看到,插件是满足一定接口协议的业务模块。

三、混乱的界限

作为控件使用的插件

如果一个插件中只有一个控件,并且没有其他的业务逻辑。这种情况下它是插件还是控件?

就像上面所说的,插件是带有一定业务的模块,并且是直接面向用户作为一个系统功能来体现的。插件仅仅是封装了一个控件,并没有带有其他的业务。像这种模块是作为其他插件的子插件使用。如下图所示。

这和我们上面看到的插件内部直接包含控件就不一样了。控件作为子插件的形式被其他插件使用。

插件的配置文件中会将自身的属性作为配置,如标题、图标、和其他一切可以作为配置的元素。但子插件没有详细的配置文件,它的属性直接通过插件的接口暴露给父插件。

这类的子插件是介于插件与控件之间的“伪插件”,因为它并不能独立地在系统中运行,并且通常情况下不带有业务逻辑,不能直接给用户带来价值。

发布后可更换控件

伪插件似乎没有什么好处,谁会无缘无故地在控件之上再封装一层作为插件来使用?

可以想象一下,在系统发布后,我们需要改变某些插件中使用的控件。当然,可以将那些插件全部重新编译后发布。但如果使用这种“伪插件”的思路,我们可以开发一个满足同样接口的另外一个伪插件,并在内部使用不同的控件实现。这样就可以在不发布其他插件的情况下,灵活地修改我们使用的控件了。

额外开销

如果所有的控件都像上面的来实现,那简直是一场恶梦,并且也没有这个必要。因为这样做的成本比较大。至于实际中是直接用控件,还是用伪插件的技术,那就要看我们的决策了。

关系模式-万能观察者

插件的独立性与插件之间的依赖关系是插件框架必须解决的问题。

其中独立性与插件的划分粒度相关,将每一个插件实现为一个dll,从物理层面强制保证了插件的独立性。插件之间的依赖关系是要解决的更加复杂的一个问题。

一、观察者模式

我们将系统分割成一系列相互协作的类,常见的会有一个副作用:需要维护相关对象间的一致性。但我们并不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。(引用自GoF的《设计模式》)

在Subject的某一个固定时刻,将会调用Observer的Update通知观察者。

二、观察者的进化历程

2.1 增加观察兴趣

上面只是考虑到了一种简单的情况,即相互协作的类之间只会有一种交互。但通常在系统中交互的场景并不只是一种。也就是说观察者类型(接口)并不仅仅是一种,而是两种或多种。

这时候我们不能简单地在Subject中存储一个FObservers列表了事,也许要存上多个。如下图:

或者我们专门用一个观察者列表的管理器来管理这么多的观察者接口:

2.2 推模型VS拉模型

从上面的说明上可以看到,将观察者需要的信息通过Update方法传给观察者,这是“推”模式。另外还有一种情况是由观察者收到Update通知后,主动从目标取信息,这是“拉模式”。推模式和拉模式表明了触发更新的角色。

2.3 观察列表的统一管理

如果需要观察者触发更新,那么需要在观察者中保存对目标的引用,让观察者能在适当的时候调用Notify 方法。同时,在一个系统中,目标和观察者都是相对的概念,对于一个模块来说,在有的应用中作为目标存在,另外一些应用中又是作为观察者存在。

经过分析后,可以将观察者管理器统一处理,作为一个目标与观察者的注册中心。

三、通用关系——主体、客体

3.1 关系管理器

现在的观察者已经和原有的观察者模式有了比较大的区别,观察者的注册中心存储的并不仅仅是观察者列表,而是“目标-观察者”对,通过一个目标可以找到若干个对应的观察者。如下图所示:

关系是对象之间交互的描述。在我们的系统中,对象指的是接口。任何一个模块都可以找到和自己关联的某一类接口,模块之间通过接口交互。注册中心的实质是管理模块之间的交互,作为一个关系管理器存在。在一个“目标-观察者”交互中,目标触发交互过程,观察者接受信息。可以将一次交互分为“主体-关系-客体”三个部分,等同于语法中的“主谓宾”结构,至于那个模块是主体,那个模块是客体,那就要看在关系管理器中的定义。

3.2 关系的注册

在观察者模式中,我们需要调用Attach与Detach来注册、取消观察者。将目标与观察者的概念进一步抽象成对象与对象之间的关系后,我们不再需要调用目标的Attach与Detach方法了。一切都是关系管理器的职责。

在关系管理器中提供Register与Unregister来完成类似的功能,通过FindRelated来查找观察者列表,这样可以实现观察者模式中的功能,并且可以方便地扩充观察点。

四、应用场景

插件系统中要解决的两个重要问题:独立性、依赖性。这两个特性有着矛盾的地方,不过通过接口可以有效地实现模块之间的隔离。当一个系统中只有十几个模块的时候,交互不是大的问题,但当系统中存在上百个模块时,就需要对模块之间的交互进行管理。

关系模式是一种对象交互模式,上面描述的关系模式是在关系模式的基础上的一种发展,比较适合在插件系统中管理插件之间的交互关系。并且这些关系是可定制的。具体的定制方式和实际的业务有很大关系,这里不再细说。

目前已经在插件系统中应用关系模式,但我认为这个思想是可以借鉴到其他的系统中的。

系统集成方案

一切都是为了更加简单。

从函数到函数库,然后到类,然后到插件,都是因为我们的软件系统日益复杂,人脑毕竟有限,不能同时处理那么多的信息量,所以采用分而治之的方法来管理。

今年已经研究了一年的插件系统,从最开始的懵懵懂懂到现在能有些经验和大家分享,这个过程本身就是很有意思的。

最开始系统中有了十几个插件,经过几个月的慢慢发展,到了大几十个,甚至上百个,这个数量就有些令人头晕了。不过更加麻烦的还不是这近百个插件组装而成的系统,而是某一个插件系统需要调用另外的一个或多个插件系统。这样的话,插件的数量就在100的基数上开始翻倍。

如何做插件系统中的整合成了一个紧急的课题。

一、插件系统基本结构

前面写过一篇文章,说到了插件系统中的微内核与巨内核之分。不过不管是哪一种,任何一个系统都需要有一个启动点,只不过对于插件系统中的启动步骤来说,它是一个通用,并且和具体业务无关的独立模块。可以按照下面的图示来简单理解插件系统:

图中的Launcher是插件系统的启动模块,EntryPoint是系统的入口点,作为一个接口给Launcher调用。启动模块通过EntryPoint将系统运行起来。系统中的插件相互协作满足用户的需要。

二、开始集成

上面的图将一个插件系统的基本原素描绘出来了。在具体的项目中,这样的一个插件系统中插件的数量可能多达上百个。当两个项目组都在开发各自的产品,项目组A需要将项目组B开发的系统集成到自己的系统中时,就要开始考虑集成的问题了。

系统中的插件之间存在父子关系,任何一个插件都可以作为另外一个插件的子插件存在。

如果将系统B作为系统A中某一个插件的子插件是不是就可以解决集成问题了呢?——不错,一个简单但实用的解决方法。

可以将插件系统考虑成一个函数库,函数库中的几百个函数相互协作完成一系列复杂的功能。现在我们需要在自己写的函数中包含上面函数库中的所有功能怎么办,简单的做法是将函数库中的某个入口函数作为子函数调用就可以了。

下面介绍的集成方案基本上就是这个思路。

三、插件系统集成解决方案

3.1 EntryPoint与Endpoint

EntryPoint是插件系统的启动模块调用系统功能的接口,这个接口是非常简单的,很多时候仅有一个Run 方法,直接对应到用户的双击打开程序的操作。

在系统A中要调用系统B时,显然一个简单的Run方法不能满足要求,这里另外提出一个系统的入口点(端点)Endpoint。

两者的区别在于,EntryPoint对应到Launcher的启动过程,参数简单;Endpiont对应到其他系统的交互过程,参数复杂,需要通过Endpoint传递其他系统需要的信息。

3.2 BUS

有了每个系统的端点,还需要将这些端点组合起来,保证插件系统之间的相互通信。类似于电脑中的总线概念。一旦每个系统的Endpoint挂接到了总线上,插件系统就可以通过总线查找到自己需要交互的其他插件系统了。

这里的总线用关系管理器来实现。因为Endpoint在插件系统中也是作为一个插件存在,这个插件的职责就是和外界交互。关系管理器可以处理任何插件之间的交互,尽管插件并不在同一个系统中。

3.3 Linker

在系统A中呈现系统B的功能有多种表现形式,比如说在系统A的某个地方放上一个Button,点击后系统B出现;或者在系统A中放上一个页签,和一般功能并列将系统B呈现在系统A中。不管怎样呈现,可以将系统B看作系统A的一个插件。这个插件就是图中的Linker。

Linker是系统B的一个代理插件,它本身并没有实现业务,只是将与系统B的交互以插件的形式呈现在系统A中。Linker通过总线找到对应的插件系统并将它启动,同时负责与它的交互。

四、适配器模式

Endpoint用的是Adapter的思想,将自身系统的功能以规定好的交互方式发布到总线上,这样其他插件系统才能与之进行交互。这种方法在系统的集成中用得非常多,已经从设计模式上升到了架构模式的层次。有了这种适配器的方式,不仅仅是插件系统可以集成,甚至非插件系统同样也可以集成到插件系统中来。所作的就是需要给非插件系统提供一个Adapter插件。对于其他插件系统来说,这个非插件系统在BUS的表现也和插件系统没有差别了。

五、说时容易做时难

上面提出了一种插件系统的集成方案,目前正在逐步的尝试,过程中还遇到了一些细节上的问题,今后等我慢慢整理出来再和大家分享。

现在只是做了插件系统与插件系统之间的集成,虽然从理论上说,插件系统与非插件系统的集成也同样可行,不过目前还没有实践,不敢妄下定论。等有了机会再好好研究一下这方面的内容。如果哪位朋友有一

些好的经验愿意分享,在下洗耳恭听

玩积木的程序员

自从我学习程序设计开始,就不断地听到大家谈论面向对象。在最开始接触C++时,确实被它的OO特性迷住了,相比之前用过的C语言更加丰富多彩。想当初,经常因为写出了一个类而暗自自豪半天。

现在做程序员也有些年头了,回过头来看以前似乎领悟到的OO思想又有了一些新的感悟。

一、代码之外的对象

提起OO,大家都会想到class关键字。以前老师这么教的,平时自己也是这么用的。虽然有些语言中的表现不一样,但本质上都是差不多的。刚开始时,说OO是一种技术;后来说OO是一种潮流;再后来说OO 是一种信仰;后来的后来说OO是一种思想,总之是越说越玄。

不过有一点却是肯定的,我们可以将OO思想用在不支持OO特性的语言中。比如说,学了C++的人去写C程序,很可能写出来的还是C++风格的。

进一步推理,OO思想可以在语言之外体现出来。

年初就开始做插件系统方面的东西,做到现在系统中的插件有好几百个。对于这样的系统来说,插件就相当于非插件系统中的对象。没有谁规定对象必须是class创建出来的。在以前写的文章中,有朋友的评论说到,这种情况可以叫做“对象模型(Model)”,和我这里说的是一个意思。

插件分为代码和配置两个部分,代码实现插件的业务,配置文件处理插件特性和插件之间的交互关系。可以说,在插件系统中,代码加配置组成的那个东西也能叫做“对象”,也就是代码之外的对象。

当我们能将OO思想摆脱代码的局限时,那么就能拥有更加广阔的思考空间了。

二、组合优于继承

封装、继承、多态是面向对象的三大特性。对于插件来说,封装是能很好地表现出来,但对于继承和多态却非常难实现了。至少我现在还没有看到有人将插件做成支持继承的。

以前有人问我觉得面向对象的三个特性中哪一个最有意思。当时我回答是多态,因为它最灵活。多态是和继承绑定的,继承是一种强耦合,也就是说派生类和基类不可解耦。在有些时候继承和多态能带来意想不到的好处,但更多时候我们需要用组合来代替继承,以此获得更大的灵活性,尤其是站在系统的层面。比如说有两个模块功能非常接近,如果按照派生的思路,在这两个模块之上提出一个基类,继承两个子类来完成具体的功能。对于代码之中的对象这样做没什么问题,但对于代码之外的对象,只能采用组合来代替派生的思路了。做法是将两个模块的公用部分做成一个公用子模块C,不同部分做成A、B两个模块。A与C组合起来生成第一个模块,B与C组合起来生成第二个模块。

还有一种解决方法就是用配置来处理模块特性,大家可以参考我以前写过的文章。

在设计模式中也强调“组合优于继承”。

三、好积木的要点

将软件模块比作积木,我们程序员就是玩积木的人了。各种各样的类库和框架、加上形形色色的控件,都是我们玩的积木。在插件系统中,插件就是积木。本文的着重点是插件系统。

好的“积木”需要具备以下的几点:

1、可插拔性,动态加载

2、外观可调

3、显示位置可配置指定

4、统一的列表管理

5、元素之间可通讯

上面介绍一些基本的要点,也是插件系统需要解决的若干个问题。上面的这些问题在以前的文章中已经简单介绍过。解决上述问题的方法多种多样,很感谢那些和我分享自己解决方法的朋友们:)

在现在的项目中,最关键的一点就是“配置”,这就要求满足1、2、3点,而4、5点则是将插件组装成完整系统的必备因素。

四、什么是技术含量

粗略地可以将程序员分成两类:做积木、与玩积木的人。

做积木的人指的就是那些自己写控件、插件的人,玩积木的人指的就是将各种各样控件或插件组装成系统的人。在业界大多数人都会认可那些自己写控件的,对于“只会拖拖控件”的程序员则不屑一顾。

我们很难说做积木与玩积木的人哪一个水平高,因为需要的是两种不同的能力。做积木的人需要对底层计算机技术有深刻的了解,而玩积木的人则需要对业务、用户需求和整体框架有清楚的认识。两个层面的人都需要有优化的意识。

很多学生的眼中,技术含量指的就是学习系统底层知识,掌握计算机原理;但工作过一段时间,尤其是做行业软件的程序员则会有不同的看法,他们更加关注怎样来“玩积木”,同样是一门学问。这也就是设计模式在学生中很少有人知道,而算法等基础理论离职业化程序员越来越远的原因。

我们不能仅仅按照做积木和玩积木两种类型来区分技术含量,不同的工作对技术的侧重点不一样。不过在我看来,玩积木才是我真正想做的事情,也可以说是架构设计了。当然,成为一个优秀的架构师还是相当困难的。

隐喻的力量

隐喻是由团队提出一个程序工作原理的公共景象。它可以帮助我们从整体上把握系统的全局,使得描述问题非常直观。

团队在做插件系统的时候,我们拿到的只有Rose图,和一些基本设计的思路文档,但对于插件系统究竟是什么,每个人的理解深度、方式都不一样。究其原因,就是因为我们没有一个直观,形象的描述系统的一个东西。概要设计文档是不能算的,太粗且不形象。这个时候我们需要的就是一个隐喻系统,帮助团队统一认识,使得交流更加有效,或者更加有趣。

一、插件是什么

插件就是积木。

积木有自己的形状、颜色、质地。

1、积木的形状是插件的接口,只要两个积木的形状吻合——两个插件的接口匹配,就可以组合起来。

2、积木的颜色是插件的外观,对于一个已经集成到系统中的插件,外观是可以随意变化的,也就是说系统是否能正确运行和插件拥有什么样的外观没有关系,只是不同的外观会带来不同的用户体验。当然外观也是非常重要的。

3、积木的质地是插件的实现,同样对于系统来说,插件的实现是可以随意修改的,只要形状一样就可以集成进来。也许积木在不同的地方摆放对实现的要求是不同的。比如说要放在积木的最低层,但却是用海绵做的一块积木,这样上面的积木非常容易倒。如果一个插件是非常基础的插件,但在实现上性能不够好,依赖于它的插件可能就根本跑不起来。

4、积木是可以组合的,两个或多个积木组合在一起可以当作一个大的积木来用。两个或多个插件组合在一起同样可以当作一个大插件来用。

5、积木可以重用。以前在其他地方用过的积木可以拿到这次来使用。对于以前开发过的插件,一样可以重复使用。

二、插件系统是什么

插件系统就是由积木按照意愿搭出来的模型。

1、积木可以并行制造——插件可以并行开发。

2、积木可以随意组合——插件系统可以根据配置来生成。配置文件就相当于搭积木时的图纸,虽然都是同一些积木,但根据图纸可以搭出不同的东西。

3、玩积木分三个阶段,做积木、搭积木和搭好积木后叫人过来观赏。插件系统分三个阶段,做插件、组装插件、生成系统给用户使用。

4、搭积木很繁琐,并且需要创造力——插件系统组装很累。

5、积木质地不够好,或者两个积木本来形状不匹配却放在一起,这样搭出来的东西容易垮掉。插件系统

中,如果插件实现有问题,或者配置文件有问题——将接口不匹配的插件组装起来,这样很容易造成系统崩溃。

6、积木搭出的模型可以随时修改。插件系统能更好地面对用户变化和地区特性。“什么,用户不要这个功能?”那从系统中拿掉好了。“这个功能用户想要改一下?”那把这个插件修改就好了,其他地方没有影响。

三、用户不要积木

系统最终用户并不关心你的系统是用什么技术实现的,他们只关心买这个软件是不是真的能帮他们做事(一群没有艺术鉴赏力的家伙)。但软件的核心是用户,所以虽然我们采用的是插件技术,但却不能把一堆插件丢给用户,说“你想要什么就自己搭吧,想要的都可以搭出来。”

插件只是半成品,不能给用户带来商业价值,所以我们需要将插件组装成一个真正的系统再交给用户。有点像现在可以买到的拼图游戏,一个盒子里面装的全是纸屑、碎片,一般还有一张最终效果的示意图,没什么人会觉得这些纸屑可以给人带来美的享受。只有等到好事者们将这些纸屑一块一块拼接起来,我们才会发现“哦,原来这幅画还蛮好看的。不过这张纸好像到处都裂开了,影响美观。”

说这些的意思就是,用户不要积木,并且要尽量地将积木这个事实从用户的视角上掩盖掉,然后告诉他们,我们的系统是变形金刚。这样就好了,让他们琢磨去吧。

四、不太好的隐喻

将插件比作积木的隐喻能解决很多问题。包括我随后会写的关于插件系统组装策略的解释。这样的隐喻能更加形象地告诉别人插件是什么东西,交流起来更加方便。

不过我想的这个隐喻并不能涵盖所有的问题。比如插件之间的动态交互就不能用积木隐喻来解释。不过暂时没有想到更好的。

关于隐喻有一点要说明的,隐喻最好从自然界或者社会人事中来,这样更加容易理解。如果团队中有一种领域是大家都了解的,那也可以。比如说如果团队对足球都很清楚,那么用球队来比喻某个系统同样是可以的。

原则就是,要用具体的东西来隐喻抽象的软件系统。如果用抽象来隐喻抽象,那只是换了个说法,没有任何意义。

最简单强大的插件框架

最简单强大的插件框架 什么是开放工厂 开放工厂是一个敏捷、开放、共享、协作、社会化的软件生产线平台。它向开发者提供了规范化的https://www.doczj.com/doc/3b18139471.html,插件框架和可复用的插件仓库,致力于解决应用系统的模块化敏捷开发、团队无缝协作和自动化部署问题。 开放工厂向软件开发商提供了共享的插件仓库。目前共享插件仓库拥有超过100个的可直接使用插件,涵盖了桌面界面框架、Web界面框架、数据库访问、数据挖掘、数据集成、大数据支撑、消息队列、数据加密、文件访问等各类插件。 开放工厂向软件开发商构建了一条自动化的敏捷软件生产 线平台。这个生产线平台能够极大提高软件开发效率、团队协作效率,使软件的生产变得和生产线组装一样。 在这里,开发团队从插件仓库获取基础插件并进行组装,在此基础上根据实际需求开发业务逻辑插件,并将业务插件通过自动化部署工具发布/更新到插件仓库。 测试团队则从插件仓库获取需要测试的插件及其更新包组

装成软件进行测试,一旦发现问题则反馈给开发团队。 部署团队从插件仓库获取需要部署的软件系统的插件进行 安装,并利用开放工厂自动升级功能实现自动化的部署。 开放工厂为软件开发商提供了自动化部署机制,为软件提供商提供了持续部署和持续交付能力,实现了最高级别的“DevOps”。 在这里,当插件变更需要发布时,开发团队通过鼠标右键即可将插件及其后续升级包持续的发布到插件仓库;管理人员则可以对插件仓库进行管理。 一旦插件仓库产生变更后,实际部署环境则通过自动升级/降级机制保持与插件仓库版本一致,实现应用系统的自动化持续部署。 开放工厂所有插件基于https://www.doczj.com/doc/3b18139471.html,面向服务插件框架构建。该框架是国际上第一个完整迁移了OSGi R4规范的https://www.doczj.com/doc/3b18139471.html,框架,提供了动态模块化、面向服务和模块扩展三大功能,支持WinForm桌面应用、WPF桌面应用、https://www.doczj.com/doc/3b18139471.html, Web应用、https://www.doczj.com/doc/3b18139471.html, MVC应用、Silverlight RIA 应用、手机应用等任意.NET应用环境。开放工厂架构

常见流氓软件、插件一览表

见流氓软件、插件一览表(不全) 1 很棒小秘书 广告软件 上海很棒信息技术有限公司 强制安装、无法彻底删除、弹出广告、自动变形 2 DMCast桌面传媒/IE-BAR 广告软件 千橡〈----恨,就是它的广告让我中了7939 弹出广告、无法彻底删除、强制安装、浏览器劫持 3 开心运程速递插件 广告软件 https://www.doczj.com/doc/3b18139471.html,/ 强制安装、无法彻底删除、弹出广告 4 InsII&III 广告软件 未知 弹出广告、强制安装、无法彻底删除、自动变形 5 EliteBar 广告软件 未知 弹出广告、强制安装、无法彻底删除、劫持浏览器、窃取用户隐私 6 https://www.doczj.com/doc/3b18139471.html, 广告软件 未知 弹出广告、强制安装、无法彻底删除、自动恢复 7 TargetAD 广告软件 很棒 弹出广告、强制安装、劫持浏览器、无法彻底删除 8

ADDeliverer 广告软件 未知 弹出广告、劫持浏览器(篡改首页)、强制安装、无法彻底删除、 9 多多QQ表情 广告软件 https://www.doczj.com/doc/3b18139471.html, 强制安装、弹出广告、无法彻底删除、自动变形 10 DmPlay弹广告软件 广告软件 未知 弹出广告、强制安装、无法彻底删除 12 WinStdup 广告软件 https://www.doczj.com/doc/3b18139471.html, 强制安装、弹出广告、无法彻底删除、自动变形 13 MSIbm 广告软件 未知 弹出广告、强制安装、无法彻底删除 14 iShare 广告软件 未知 弹出广告、强制安装、无法彻底删除 15 Cnnic中文上网 浏览器劫持 中国互联网络信息中心 强制安装、无法彻底删除、干扰其他软件运行、浏览器劫持 16 Cnnic无忧上网工具条 浏览器劫持

基于插件及构件技术的软件工程

基于插件及构件技术的软件工程听课心得今天我们上了王斌老师的课,王老师对基于插件及构件技术的软件工程做了详细的讲解,使我对这个领域也有了一些粗浅的认识,有了一些自己的理解。 软件工程(Software Engineering,简称为SE)是一门研究用工程化方法构建和维护有效的、实用的和高质量的软件的学科。它涉及到程序设计语言,数据库,软件开发工具,系统平台,标准,设计模式等方面。在现代社会中,软件应用于多个方面。典型的软件比如有电子邮件,嵌入式系统,人机界面,办公套件,操作系统,编译器,数据库,游戏等。同时,各个行业几乎都有计算机软件的应用,比如工业,农业,银行,航空,政府部门等。这些应用促进了经济和社会的发展,使得人们的工作更加高效,同时提高了生活质量。 而软件体系结构则是具有一定形式的结构化元素,即构件的集合,包括处理构件、数据构件和连接构件。处理构件负责对数据进行加工,数据构件是被加工的信息,连接构件把体系结构的不同部分组组合连接起来。这一定义注重区分处理构件、数据构件和连接构件,这一方法在其他的定义和方法中基本上得到保持。 随着计算机技术的发展,软件体系结构和开发方法也在发生着重大变化。为了高效率地进行软件研发,开发出高质量的软件产品,人们一直在寻求更好的软件体系结构和开发方法。插件式体系结构是一种非常灵活的组件式结构,它把程序的功能分散在插件中来完成。插件是可独立开发的程序模块,它能够动态地插入到系统中,并且可以被自由地删除和替换。因此它能够提高软件开发的并行性和开发效率,降低设计开发难度,缩短开发周期,增强应用程序的可运行性、可测试性和可维护性。文章以蓝星多媒体教学软件为对象,对基于插件技术的软件架构的设计、实现及应用进行了分析研究。首先,分析了基于插件技术的软件系统的原理与运行过程,找出插件软件系统的五个关键之处,并对这五个关键点的设计模型进行了说明。其次在基于这些设计模型的基础上提出了一种新的设计方案,并将此设计方案应用到蓝星多媒体教学软件的开发设计之中。最后通过一个实验证明了此技术的可行性与实用性。实践证明,基于插件技术的软件架构可以有效地解决软件开发过程中的

试谈计算机软件中的插件技术

SOFTWARE DEVELOPMENT AND DESIGN软件开发与设计 1引言 一个可以挂接插件的软件系统,通常包括主程序(host)和插件(p1ug-in)组两个部分。独立的主程序和插件能够互相结合在一起工作,必须有一套互相协作的规则和协议,使不同来源的程序互相协调工作。这些规则和协议称为插件系统的接口。插件可以由动态链接库实现,主程序根据接口规则,调用插件的功能,同时还可将任意插件接口在内存中的地址传递给每个插件,插件则根据这些地址来调用其他插件函数,完成所需功能、获取所需资源等。 2插件技术的原理 2.1动态链接库 动态链接库(Dynamic Link Library)是一种具有一定功能的可执行软件模块,虽然它本身不能独立运行,但是它可以输出函数或类,通过其他能独立运行的程序(宿主程序)可以调用它内部的功能。动态链接库有两种调用方式: 2.1.1静态调用方式 由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(如还有其他程序使用该DLL,则Windows对DLL 的应用记录减1,直到所有相关程序都结束对该DLL的使用时才释放它),简单实用,但不够灵活,只能满足一般要求。隐式的调用需要把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只需说明一下。隐式调用不需要调用Load Library()和Free Library()。程序员在建立一个DLL文件时,链接程序会自动生成一个与之对应的LIB导入文件。该文件包含了每一个DLL导出函数的符号名和可选的标识号,但是并不含有实际的代码。LIB文件作为DLL的替代文件被编译到应用程序项目中。当程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与LIB文件中导出符号相匹配,这些符号或标识号进入到生成的EXE文件中。LIB文件中也包含了对应的DLL文件名(但不是完全的路径名),链接程序将其存储在EXE文件内部。 2.1.2动态调用方式 是由编程者用API函数加载和卸载DLL来达到调用DLL 的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。 显式的调用是指在应用程序中用Load Library或MFC提供的Afx Load Library显式的将自己所做的动态连接库调进来,动态连接库的文件名即是上面两个函数的参数,再用Get Proc Address()获取想要引入的函数。自此,就可以使用如同本应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用Free Library或MFC提供的Afx Free Library 释放动态连接库。直接调用Win32的Load Library函数,并指定DLL的路径作为参数。Load Library返回HINSTANCE参数,应用程序在调用Get Proc Address函数时使用这一参数。Get Proc Address函数将符号名或标识号转换为DLL内部的地址。程序员可以决定DLL文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件。使用DLL的程序在使用之前必须加载DLL从而得到一个DLL模块的句柄,然后调用Get Proc Address函数得到输出函数的指针,在退出之前必须卸载DLL(Free Library)。 2.2接口 开发支持插件功能的应用程序必须解决一个问题:如何在宿主程序与插件间正确地相互通信。俗话说“没有规矩不成方圆”,为了在宿主程序与插件间能正确地相互通信,应该先制订一套通信标准,这套制订好的通信标准就是接口,宿主程序与插件只能通过制订好的接口进行通信。软件开发中,接口只是定义功能并规定调用功能的形式,而不包含功能的 试谈计算机软件中的插件技术 陈国栋 (山东省电力学校教育技术科,泰安271000) 摘要:应用插件技术,可以很好地提高软件的重用性和扩展性,解决软件合作开发与集成问题具有很好的理论和 实用价值。介绍了插件技术的原理,阐释了插件的实现方案,提出了插件技术在地震处理插件系统中的应用。 关键词:插件;接口;插件技术 Talk on the Computer Software Plug-in Technology CHEN Guodong (Shandong Electric Power School Education Technology Section,Tai'an271000) Abstract:The plug-in tech nology can be good and improve software reusability and scalability to address software co-development and integration issues,has a good theoretical and practical value.This paper analyzes the principle of plug-in technology,explains the plug-in implementation of the program,proposed seismic processing plug-in system. Key words:plug;interface;plug-in technology 作者简介:陈国栋(1979-),男,本科,助理讲师,现从事 计算机教学工作。 收稿日期:2010-06-16

Psunami插件详细教程

Psunami插件详细教程 一、参数介绍 Psunami插件的所有属性都被组织在不同的属性参数组中,它们是Presets(预设)、Render Options(渲染选项),Air Optics(大气光学)等十二个参数组。我们可以通过单击挨着该组名称附近的箭头使它向下来打开每一个参数组来访问该类型参数组的属性,或者折叠每一个参数组释放屏幕空间降低屏幕的混乱。 当在After Effects软件中为一个素材层第一次应用Psunami插件时,该插件将使用它的默认属性设置,此时摄像机设置在离大海表面10米的仰角位置,直接面向太阳而角度稍微向下向着水面。同使用所有的After Effects软件插件一样,在任何时候,你都可以在效果控制窗口中挨着插件名称的附近单击RESET按钮,通过此举可以返回到其默认设置。 单击About插件信息按钮将打开Psunami插件的版本信息对话框 二、Psunami插件效果控制窗口中的各个参数组以及大部分参数。 1、预设参数组 在Psunami插件的效果控制窗口中看到的第一组属性是Presets(预设),单击预设左边的转动箭头使它向下可以露出预设的控制面板,通过预设面板可以打开和应用Psunami插件所预先设定的参数,这些参数是一些属性的集合。当应用某个预设时,可以选择哪一个属性将受到调整影响,把自己的预设按照某些种类组织,保存,更名以及删除预设和种类,并且可以重新把所选择的属性组设置为默认值而需不重新设置它们。 注意:预设面板分成了3个部分:Load(加载),Save(保存)和Reset(重新设置)。 在加载部分中,可以使用预设下拉菜单来加载和应用预设,而且可以选择是否把所有的属性组都应用在该预设中,或者是只应用所选择的某组属性。 要选择一个预设,在Preset下拉菜单上单击,将看到一个预设类型下拉菜单 在该列表上一共有12种类型,它们每一项右边都有二级菜单黑箭头;说明它们都具有二级菜单。打开二级菜单,然后在其上面拖动到某个预设来选择它 为了对Psunami插件层应用该预设的所有属性,从Property(属性)下拉菜单上选择All (所有)选项,然后单击GO!按钮。直到单击GO按钮后,才应用所选择的预设。为了对Psunami 插件层应用某个单独的属性,从Property(属性)下拉菜单上选择想要的属性组,不选择其他的属性,然后单击GO!按钮。只须通过在每一次选择该组属性后并且单击GO!按钮,还可以选择其他的属性组来应用。 Psunami插件提供了许多可以直接使用的预设,可以把这些预设作为自己实验的起点,当第一次安装Psunami插件时,它在After Effects软件的plug-ins文件夹中建立一个称为Atomic Presets的文件夹。该文件夹内是Psunami文件夹,在Psunami文件夹中可以发现有若干的预设类型子文件夹,这些文件夹中包含了软件提供的预设,存储的预设和类型也将同样被保存在这里。请切莫移动或者重新命名这些文件夹,否则将可能不能够加载预设。

Linux插件框架实验报告

电子科技大学 实验报告 学生姓名:学号:指导教师: 实验地点:A2-412 实验时间:2012.01.04 一、实验室名称: Linux环境高级编程实验室 二、实验项目名称: 插件框架实验 三、实验学时: 4学时 四、实验目的: 学习和实践插件框架的开发。理解插件的工作原理,为进一步开发高可用,高复杂度的插件打下基础。 五、实验内容: 1、使用动态链接库实现打印功能: 开发一个程序,向屏幕打印“Hello World”;在不重新编译链接原程序的前提下,将打印的文字改为“Hello China”。 2、使用动态链接库实现自定义打印功能:

同时要打印“Hello World”,打印“Hello China”,甚至同时打印未来才会增加的其他打印信息,打印信息的链接库放在一个固定目录中,遍历这个目录,获取所有动态链接库。 打印未来的这些信息,也不能重新编译链接原程序。 3、 1)通过命令行方式:./a.out help,输出所有插件实现的功能ID,以及该功能ID对应的功能描述。 2)通过命令行方式:./a.out FuncID,调用具体打印功能(每个插件导出GetID接口)。 4、将插件导出的Print、GetID、Help三个函数放在一个类中,主程序需要使用多个容器分别保存这些函数地址,让插件外部获取该类的对象。 综合练习:实现一个软件系统,该系统可对文件进行统计分析。究竟对文件进行什么样的统计分析,最终用户自己也不是很清楚,目前只知道需要统计文件的行数。也就是说,本软件系统将会随时面临,增加文件统计新功能的难题。请结合本实验内容,设计并实现这样一个面向文件统计功能的插件系统。(需要实现的插件包括:统计某个文件的行数,统计某个文件的字节数) 六、实验步骤: 程序1: A.h: extern "c" void f();

3DMAX插件全集-含下载地址

3DMAX插件全集-含下载地址~ max渲染插件(高级渲染器) 3DS MAX 6由众多的插件组合而成,每个插件实现一部分功能,3DS MAX 6就像一个容器,将能各式各样能实现各种功能和效果的的插件组合在一起,使每个插件都有条不紊地工作,从而形成了功能强大的3DS MAX 6。以下提供的插件基本上是6.0版的.其中注明R5为5.0版的 插件分为两种:Standard MAX plug-ins(标准插件)和Additional MAX plug-ins(附加插件)。在3DS MAX 6的安装目录下有两个文件夹,stdplugs和plugins,其中stdplugs用来存放标准插件,plugins用来存放附加插件。 -> RealFlow 2.5 for Max6(流体设计) -> Cloth Fx v1.26 For 3dsMax 6(衣服) -> AfterBurn3.1 FOR 3DSMAX 6(焰火,云烟) -> ACT 1.6 (角色肌肉动画系统) -> Archvision rpc(RPC全息模型) -> AI Implant(群体动画适时互动的智能插件) -> BonesPro v3.0 肌肉蒙皮插件 -> BodyStudio 2.0(身体造形) -> ClothReyes 3.11(制作衣服的插件) -> CartoonReyes 2.0 卡通渲染插件 -> Darksim SimbiontMAX (生成千变万化的材质) -> Deeppaint v2.1.1.4(贴图编辑工具) -> Digitalpeople 人物制作插件。digimation公司出品的产品 -> Dreamscape 2.1 山水制作插件 ->Druid v1.2 For R5 做草的插件 -> GroundCrew 地面 -> Glu3D v1.1.47 流体插件 -> Hair1.01.18 毛发生成器

C++实现的一种插件体系结构

C++实现的一种插件体系结构 本文讨论一种简单却有效的插件体系结构,它使用C++,动态链接库,基于面向对象编程的思想。 首先来看一下使用插件机制能给我们带来哪些方面的好处,从而在适当时候合理的选择使用。 1,增强代码的透明度与一致性:因为插件通常会封装第三方类库或是其他人编写的代码,需要清晰地定义出接口,用清晰一致的接口来面对所有事情。你的代码也不会被转换程序或是库的特殊定制需求弄得乱七糟。 2,改善工程的模块化:你的代码被清析地分成多个独立的模块,可以把它们安置在子工程中的文件组中。这种解耦处理使得创建出的组件更加容易重用。 3,更短的编译时间:如果仅仅是为了解释某些类的声明,而这些类内部使用了外部库,编译器不再需要解析外部库的头文件了,因为具体实现是以私有的形式完成。 4,更换与增加组件:假如你需要向用户发布补丁,那么更新单独的插件而不是替代每一个安装了的文件更为有效。当使用新的渲染器或是新的单元类型来扩展你的游戏时,能过向引擎提供一组插件,可以很容易的实现。 5,在关闭源代码的工程中使用GPL代码:一般,假如你使用了GPL发布的代码,那么你也需要开放你的源代码。然而,如果把GPL组件封装在插件中,你就不必发布插件的源码。 介绍 先简单解释一下什么是插件系统以及它如何工作:在普通的程序中,假如你需要代码执行一项特殊的任务,你有两种选择:要么你自己编写,要么你寻找一个已经存在的满足你需要的库。现在,你的要求变了,那你只好重写代码或是寻找另一个不同的库。无论是哪种方式,都会导致你框架代码中的那些依赖外部库的代码重写。 现在,我们可以有另外一种选择:在插件系统中,工程中的任何组件不再束缚于一种特定的实现(像渲染器既可以基于OpenGL,也可以选择Direct3D),它们会从框架代码中剥离出来,通过特定的方法被放入动态链接库之中。 所谓的特定方法包括在框架代码中创建接口,这些接口使得框架与动态库解耦。插件提供接口的实现。我们把插件与普通的动态链接库区分开来是因为它们的加载方式不同:程序不会直接链接插件,而可能是在某些目录下查找,如果发现便进行加载。所有插件都可以使用一种共同的方法与应用进行联结。 常见的错误 一些程序员,当进行插件系统的设计时,可能会给每一个作为插件使用的动态库添加一个如下函数类似的函数:PluginClass*createInstance(const char*); 然后它们让插件去提供一些类的实现。引擎用期望的对象名对加载的插件逐个进行查询,直到某个插件返回,这是典型的设计模式中“职责链”模式的做法。一些更聪明的程序员会做出新的设计,使插件在引擎中注册自己,或是用定制的实现替代引擎内部缺省实现:Void dllStartPlugin(PluginManager&pm); Void dllStopPlugin(PluginManager&pm); 第一种设计的主要问题是:插件工厂创建的对象需要使用reinterpret_cast<>来进行转换。通常,插件从共同基类(这里指PluginClass)派生,会引用一些不安全的感觉。实际上,这样做也是没意义的,插件应该“默默”地响应输入设备的请求,然后提交结果给输出设备。

常用淘宝软件插件费用

常用淘宝软件及其插件 序号项目概述费用 1 淘宝助理上传和管理宝贝的一个店铺管理工具。免费 2 千牛工作台包含卖家工作台、消息中心、阿里旺旺、 量子恒道、订单管理、商品管理等主要 功能。 免费 3 生意参谋数据分析:流量分析店铺数据分析工具免费 4 爱用商品(高级版)商品管理:主图视频/手机详情/自动上 下架/自动橱窗/标题优化/关联销售/批 量修改/分享宝贝/库存预警10大高级 功能 32/季 59/半年 108/年 5 爱用交易(高级版)交易管理:旺旺接单/订单管理/打印发 货/物流跟踪/评价管理,付费版可使用 差评拦截/自动评价/批量打印/批量发 货/短信关怀/旺旺催付等高级功能 30/季 56/半年 99/年 6 爱用数据(高级版)数据分析:持按小时查看、访客查看、 页面查看、地区查看销售收入等功能, 及时帮助卖家掌握店铺数据动态。10/月29/季54/半年99/年 7 爱用促销(高级版)促销管理:任意折扣限时打折,季末清 仓/新品上市/节日促销/自定义/满就减 满就包邮送礼品,全店宝贝一键设置折 扣。按上架时间/节假日设置宝贝折扣。 10/月 28/季 54/半年 98/年 8 千里马全自动直通车优化插件,1次订购,即可在浏览器、千牛电脑端和手机端同时使用。提供长尾策略和爆款策略,新增千人千面算法,将有效提升ROI/点击率/展现量/点击量/销量,降低点击单价 9 美折促销促销管理:任意折扣限时打折、节日促 销、包邮、部分满就送。更有微博营销、 专区推广等特色功能,帮您增加流量、 提升营销效果。 10/月 29/季 56/半年 99/年 10 江湖策流量管理通过大数据挖掘,提供实时访 客数据,渠道推荐及转化效果数据;最 新两个新功能:买家人群画像(包含6 大信息喜好及购买力等),无线渠道效 果数据,了解买家,了解渠道效果,提 升成交转化! 免费

各种插件软件安装方法

各种插件软件安装方法 Thinkinetic Pulldownit Pro v2.1 For Maya (PDI破碎) 1.解压压缩包,双击打开Pulldownit_Pro_v 2.1_For_Maya_2010-2013_Win64bit.rar 里面提供了Maya2010-2013,四种安装版本,在这我选择了2012版本安装。 2.Ctrl+C复制Pdi_Pro_2.1_Maya2012x64文件夹,找到hxsd-我的文档-maya-2012x64 这个文件夹。把Pdi_Pro_2.1_Maya2012x64文件夹Ctrl+V粘贴在这里。 3.双击打开Pdi_Pro_2.1_Maya2012x64文件夹,找到pdiMaya文本,双击打开, 修改路径+ Thinkinetic 2.0 C:\Users\hxsd\Documents\maya\2012-x64\Pdi_Pro_2.1_Maya2012x64 并保存关闭。 4.此时在复制一份刚刚保存好的pdiMaya,并在maya根目录(C:\Users\hxsd\Documents\maya)下 新建文件夹modules,打开modules把pdiMaya放在里面。 5.重新打开Maya加载插件 blastcode1.7_for_maya2009_2011_64bit (只能在11以前版本使用的NURBS破碎) 1.找到插件所在文件夹,双击BlastCodeInstall_Trial17x64 2.一路欢脱的点击next,agree等,就能完成安装 3.重新打开Maya2009,就能在菜单栏里找到“Blast Code”菜单. 4.enjoy it! 3delight-10.0.4-setup-x64 1.双击3delight-10.0.4-setup-x64,选择English语言,并点击OK,进行下一步。 2.点击next,并选择I accept the agreement。

插件技术原理(马晟) - Google Code

马晟、张渊、刘德钢 (清华大学,软件学院,北京100084)摘要 关键词 Abstract Key words

目录 一、Eclipse体系结构 (3) 插件技术原理(马晟) (3) OSGi体系结构(刘德钢) (4) Eclipse的插件机制体系结构(张渊) (5) Eclipse发展历程(待补充,从1.0-2.0-3.0(基于OSGi)) (张渊) (5) eclipse插件的本质---容器、中间件、平台(张渊) (5) 插件是如何暴露自己接口的(张渊) (5) 插件的生命周期(张渊) (5) 插件的依赖性(马晟) (5) 插件间通信(马晟) (6) 二、OSGi插件体系结构扩展应用(有才) (13) 三、Eclipse插件机制扩展——RCP应用(德钢把内容补充完整) (13) 四、Eclipse体系结构与其他插件比较(有才) (14) 五、附录(一起维护,在自己引用的材料后面署名,排版时候统一修改) (14)

一、Eclipse体系结构 插件技术原理(马晟) 插件是一种遵循统一的预定义接口规范编写出来的程序,应用程序在运行时通过接口规范对插件进行调用,以扩展应用程序的功能。插件在英文中通常称为plug-in、plugin或者plug in。插件最典型的例子是Microsoft的ActiveX控件和COM(Component Object Model,部件对象模型)实际上ActiveX控件不过是一个更高继承层次的COM而已。此外还有Photoshop的滤镜(Filter)也是一种比较常见的插件。 插件最吸引人的地方当然就是其所实现“运行时(run-time)"功能扩展。这意味着软件开发者可以通过公布插件的预定义接口规范,从而允许第三方的软件开发者通过开发插件对软件的功能进行扩展,而无需对整个程序代码进行重新编译。运行时(run-time)是相对于编译时(assembly-time)而言的。一般来说,软件开发者对软件功能更新时,是在源代码级别进行更新,然后对整个程序进行重新编译,进而发布应用程序的新版本,这就是编译时(assembly-time)的软件更新。 插件的本质在于不修改程序主体(平台)的情况下对软件功能进行扩展与加强,当插件的接口公开后,任何公司或个人都可以制作自己的插件来解决一些操作上的不便或增加新的功能,也就是实现真正意义上的“即插即用”软件开发。平台+插件软件结构是将一个待开发的目标软件分为两部分,一部分为程序的主体或主框架,可定义为平台,另一部分为功能扩展或补充模块,可定义为插件。 在进行软件开发之前,是否采用平台+插件结构进行软件开发,还要依据具体的软件需求情况进行确定,但一般来讲,使用平台+插件结构进行软件设计会给所开发软件增加新的生命力。当确定平台+插件的软件结构之后,就要分析哪些部分功能由主体完成,即平台的基本功能,哪些部分功能由插件完成,即需要扩展的插件功能。平台所完成的功能应为一个软件系统的核心和基础,这些基本功能即可为用户使用,也可为插件使用,就是又可以把平台基本功能分为两个部分,内核功能和插件处理功能。平台的内核功能是整个软件的重要功能,一个软件的大部分功能因由内核功能完成。平台的插件处理功能用于扩展平台和管理插件,为插件操纵平台和与插件通信提供标准平台扩展接口。插件所完成的功能是对平台功能的扩展与补充,一般插件完成系列化功能,例如:PHOTOSHOP的滤镜插件完成对图形的特殊效果处理,这些功能都有一些共性,可以进行集中管理,并且是可以定义出标准的插件接口。 为了实现平台+插件结构的软件设计需要定义两个标准接口,一个为由平台所实现的平台扩展接口,一个为插件所实现的插件接口。这里需要说明的是:平台扩展接口完全由平台实现,插件只是调用和使用,插件接口完全由插件实现,平台也只是调用和使用。平台扩展接口实现插件向平台方向的单向通信,插件通过平台扩展接口可获取主框架的各种资源和数据,可包括各种系统句柄,程序内部数据以及内存分配等。插件接口为平台向插件方向的单向通信,平台通过插件接口调用插件所实现的功能,读取插件处理数据等。 平台插件处理功能包括插件注册、管理和调用,以及平台扩展接口的功能实现。插件注册为按照某种机制首先在系统中搜索已安装插件,之后将搜索到的插件注册到平台上,并在平台上生成相应的调用机制,这包括菜单选项、工具栏、内部调用等。插件管理完成插件与平台的协调,为各插件在平台上生成管理信息以及进行插件的状态跟踪。插件调用为调用各

21款强大高效的Photoshop扩展插件

Photoshop目前有很多实用的扩展和插件,合理使用PS插件既能输出好的作品又可以提高我们的工作效率,不信?可以看看今天设计达人网为大家推荐的21款优秀的免费Photoshop插件,有的插件非常强大的哦! 本文前十多款插件特别适合网页设计和做移动设备的UI设计师们使用,你会发现平时复杂繁琐的操作原来可以更简单! 1. Layrs 免费的PS扩展,能为你简化繁琐的操作,比如:图层名称编辑器、删除未使用的图层效果、合拼所有图层效果、删除空层、栅格化所有智能对象。 2. blendme.in 这插件是多数网页设计师和做手机界面的UI设计师特别喜欢的,blendeme提供很多优秀的UI设计元素,如图标、UI kits、等等。 插件提供的素材版权均为免费,格式是分层PSD或AI矢量文件。用户安装后,可以通过关键词来快速搜索资源,确实好用,建议大家装上去体验下。

3. Cut&Slice me 这个PS扩展可以智能切图和导出切片功效,并能导出不同设备类型的切片,这功能对有不同尺寸屏幕需求的设计师来说确实很好用。如果你的图层命名能符合Cut&Slice的命名规则,它导出的切片还能帮你根据设备类型来优化切图命名。

4. Render.ly Render.ly这个扩展和Cut&Slice功能类似,它有个特点就是可以给你的布局上留下说明、评论并能同步到云端。 5. CSS3Ps 可以方便的把带图标样式的图层、形状导出为CSS3、SCSS、格式。比如一些带渐变、圆角、内发光、内阴影样式的图形或文字都可以导出来。这个比一些CSS3生成功能还方便呢。

6. Composer 可以同时对多个图层进行相同的操作。 7. Web Font Plugin 网页字体插件,内嵌1000多个Google字体,方便设计师直接预览Web字体效果。 现在很多英文站都直接使用网页字体,所以这个插件用来做英文站的设计师更实用!

SUAPP插件库 1.3(永久免费版)

发布日期:2015.01.03 官方网站:http://www.suapp.me 视频教程:http://gif.suapp.me 会员中心:http://member.suapp.me 基本信息: 文件大小:3.06MB 研发团队:双鱼、麦兜、LY871108、JerryW、PaldinHao、JuneLi、FlyLi 支持系统:Windows(WinXP、Win7、Win8) MacOSX(10.7或更高版本) 软件版本:SketchUp 6、7、8、2013、2014、2015全系列 程序说明: SUAPP由双鱼和麦兜于2007年10月免费发布,改进并更新至今已逾七年。是SketchUp平台上应用最为广泛,兼容性优秀的功能扩展插件集。SUAPP1.X系列作为免费推出的产品,包含上百项功能,大大增强了SketchUp的实用性,并且完全兼容包括最新的SketchUp2015在内的所有版本。我们将保持SUAPP1.X 系列持续更新,供SketchUp新手用户永久免费使用! SUAPP1.X系列与2.X系列不同,功能较为固定不可定制,不包含高级插件功能,更新相对滞后于2.X系列。因此我们建议您付费升级到更加先进易用的SUAPP2.X系列云端插件库,获得海量插件、一键安装、个性定制、云端同步、快捷运行等高级功能和优秀服务!敬请访问SUAPP用户官方自助授权中心(http://member.suapp.me)。 升级概况: 1、影分身术(功能位置:插件菜单->SUAPP设置->影分身术) 嗯哼,不要笑。电脑上装了好几个SketchUp版本吧!?安装好SUAPP后,只需要设置关联SketchUp,SUAPP就可分身到不同的SketchUp中同时使用。 2、另存旧版(功能位置:文件菜单->保存旧版/另存旧版/保存设置,SketchUp2014~2015支持) SketchUp版本多了,文件交换就麻烦了,新版保存的文件老版本打不开!SUAPP 的另存旧版功能弥补了该遗憾,设好快捷键后根据设置直接另存或保存为旧版,便捷了很多。 3、默认程序(功能位置:包含于影分身术功能中) 双击Skp文件,打开的不是你希望的SketchUp版本,那么这项贴心小功能就派上用场了,很简单就可将某个版本的SketchUp设置为默认打开程序。 4、支持64位 SketchUp2015最新版本已于去年年底推出,包含32位版本和64位版本,性能提升较大。SUAPP目前已经完全支持2015版本,插件不再是问题,推荐大家更新SketchUp吧! 5、优化速度 速度优化无极限,SUAPP一直追求程序的稳定与性能的平衡。本次升级整理了原插件代码,清除了冗余内容,并对Ruby循环遍历筛选的代码进行优化,使部分功能执行速度提高4倍以上。

Google Chrome浏览器必备的20个插件

Google Chrome浏览器必备的20个插件 Google Chrome浏览器虽然与火狐浏览器有所区别,不过他们都是很开放的浏览器产品,所以也有许多有用的插件,这些插件对于日常生活与网络冲浪都很有用,比如网银,炒股等。 Google Chrome浏览器被称之为目前世界上最快的浏览器既简洁又高效,用来上网冲浪还真是不错。不过好马也得配好鞍,和很多非IE核心浏览器一样,Chrome也需要利用插件扩展自己的能耐。下面就是笔者精心挑选的20款实用插件,感兴趣的不妨慢慢往下看吧! 注:本文所有插件均已在Google Chrome 4.0.249.78 + Windows 7(RTM)中文版测试通过。 1. 搞定网银—— IE Tab * 推荐指数:★★★★★ * 功能概述:用IE引擎打开网页(Chrome) 虽说网页标准化已经实行多年,可事实上出于安全性或其他考虑,很多特殊的站点(如网上银行)仍旧只能用IE打开。而这款插件的最大好处,就是能够在Chrome中直接生成一个IE内核标签。插件装好后会自动在地址栏右侧生成一个按钮,每次点击都能产生一个空白 IE标签,在这个标签中拥有一套独立的地址栏及工具栏,打开的网页将享受到与IE一样的服务。此外它还有一个很人性化的考虑,那就是可以将当前页面设为“自动启动”(工具栏左数第2个按钮),换句话说当我们再次打开相同页面时,Chrome将自动以IE 模式打开。 图1 IE Tab插件 2. 鼠标手势—— Chrome Gestures * 推荐指数:★★★★★

* 功能概述:鼠标手势、超级拖拽、鼠标平滑滚动、鼠标加速滚动 鼠标手势就不用我多解释了吧,安装这款插件后,Chrome便能在鼠标的“指挥”下完成很多特定操作。除了能够显示出鼠标的轨迹,一个很人性化的设计就是提供了手势功能提示,于是我们便可以在操作时随时掌握即将发生的任务。而且这款插件还有一个特别之处,那就是实现了超级拖拽(即利用拖拽在新标签页中打开链接或文本搜索),进入“扩展程序”→“Chrome Gestures”→“选项”后即可找到这项功能。此外我们也能对默认手势进行修改,甚至为“链接”或“文字”拖拽指定不同的动作(超级拖拽)。 图2 鼠标手势 3. 超级拖拽—— Super Drag * 推荐指数:★★★★★ * 功能概述:拖拽链接以新标签打开 相信很多网友对国产浏览器的拖拽打开深有印象,这款插件便是能实现同样功能的。使用方法:将你要的链接或选定的文字拖拽一下,便能以新标签打开,或者为其展开搜索。 图3 超级拖拽 4. 撤销关闭网页—— Sexy Undo Close Tab * 推荐指数:★★★★★ * 功能概述:还原之前已关闭网页

Elasticsearch插件体系

Elasticsearch插件体系 插件分类 Elasticsearch支持三种类型的插件: 1、java插件 这些插件只包含Jar文件,并且必须安装在集群中的每个节点上。安装后,每个节点必须重新启动,该插件才变得可见。 2、站点插件 这些插件包含了静态的Web内容,如JavaScript,HTML和CSS文件,可直接从Elasticsearch 访问。站点插件可能只需要在一个节点上安装,并且不需要重新启动就能变得可见。 站点插件的内容是通过一个类似的网址访问: HTTP:/ / yournode:9200 / _plugin / [插件名称] 3、混合插件 混合插件同时包含jar文件和静态的Web内容 插件管理 命令查看 1、查看plugin命令用法: 插件安装 2、安装Elasticsearch核心插件命令格式: 例子: 该命令将安装与你的Elasticsearch版本相匹配的插件版本。

3、安装社区插件或非核心插件 非核心插件由Elasticsearch提供,或者由社区提供,可以从download.elastic.co,Maven (中央和Sonatype),或从GitHub安装。在这种情况下,命令如下: 例子: sudo bin/plugin install lmenezes/elasticsearch-kopf sudo bin/plugin install lmenezes/elasticsearch-kopf/2.x Installs the latest version from GitHub. Installs the 2.x version from GitHub. 从Maven Central/Sonatype安装时, [org]需要替换为groupId, [user|component]替换为artifactId. For plugin from Sonatype, run: sudo bin/plugin install org.elasticsearch.plugin/mapper-attachments/3.0.0 当从 download.elastic.co或Maven Central/Sonatype安装时, version 是必须的。 自定义URL或文件系统 插件可以直接从自定义URL下载,格式如下: sudo bin/plugin install [url] must be a valid URL, the plugin name is determined from its descriptor. 例如从本地文件系统安装插件: sudo bin/plugin install file:///path/to/plugin.zip The plugin script will refuse to talk to an HTTPS URL with an untrusted certificate. To use a self-signed HTTPS cert, you will need to add the CA cert to a local Java truststore and pass the location to the script as follows: sudo bin/plugin https://www.doczj.com/doc/3b18139471.html,.ssl.trustStore=/path/to/trustStore.jks install https://....

常见的十三种系统框架

最常用的系统框架都有哪些? OpenXava OpenXava是一个让使用XML与Java来开发J2EE商业应用程序变得简单的框架。它目前支持IBM WebSphere应用服务器,但在开发过程中可以使用 JBoss.OpenXava1.1版本支持以下特点: ◆支持WebSphere 5.0, 5.1和6.0, JBoss 3.2.x和4.0.x包括native EJB CMP2 EntityBeans ◆它已经被用在许多商业项目上 ◆易用,使用它可以获得高的开发效率 ◆灵活:可以在任意位置插入自己的功能。 ◆基于商业化组件的概念 ◆完全地MVC ◆使用有着成熟商业应用程序丰富特性的Web用户接口 ◆可生成整个J2EE应用程序 ◆它应用到的开源项目有:Ant, JUnit,JasperReports,TL,XDocLet,Hibernate 等 karma karma是一个轻量级并且易于使用的J2EE应用程序框架。当前它包含“COMMON”与“JCR”这两个组件。“COMMON”组件是整个框架的核心并且基于mvc模式。这个组件易于测试(提供mock对象供测试),很少的XML描述,易于学习因为它使用简单的POJO动作(actions),拦截器(interceptors)和过滤器(filters) 还提供对AJAX的支持。 “JCR”组件是一个持久层框架但它没有XML映射文件并能与其它web框架相结合如:Spring MVC框架。 Keel Framework Keel Framework是一个把专注于应用程序开发某方面(如:用户接口,数据库,消息,安全等等)的开源或商业的框架以插件的方式整合在一起的元框架。Keel围绕三种核心模式进行构建: 1.COP模式(Component Oriented Programming:面向组件编程)这就为应用程序提供了一个灵活的插件(plugging/unplugging)框架。 2.SOC模式(Separation of Concerns:关注分离)这允许用户执行/控制/修改任何组件的功能而不会影响到其它组件。 3.IOC模式(Inversion of Control:反转控制)。

相关主题
文本预览
相关文档 最新文档