AS3中的插件模式开发(一)

插件式开发是我非常喜欢的一种设计模式。实际工作中,对某一产品,经常因时间和场景的不同,需要不同的功能。比如,视频播放器,有时候需要包含贴片广告、更多推荐的全功能版本,有时候只需要播视频的基础功能;再比如一款在线游戏,可能圣诞需要上线一个活动,春节又希望上线另一个活动,但是两个活动的逻辑和功能可能完全不同,而且活动下线之后,里面的逻辑和功能可能再也用不上了。于是,为了解决这些问题,我们可以求助插件式开发。

本系列文章将在新博客更新,链接在此,请移步阅读。


插件式开发是我非常喜欢的一种设计模式。实际工作中,对某一产品,经常因时间和场景的不同,需要不同的功能。比如,视频播放器,有时候需要包含贴片广告、更多推荐的全功能版本,有时候只需要播视频的基础功能;再比如一款在线游戏,可能圣诞需要上线一个活动,春节又希望上线另一个活动,但是两个活动的逻辑和功能可能完全不同,而且活动下线之后,里面的逻辑和功能可能再也用不上了。

通常情况下,我们可以开发一个“完整功能版本”,这个版本发布后拥有所有可能用到的功能,我们通过某种开关对功能进行控制,避免太多功能分散用户注意力的同时,也保证功能更有说服力。但是这样做的话,会使代码量快速膨胀,软件结构臃肿,单个类容纳的功能越来越多,行数也越来越多;与此同时,用户每次都要下载包含所有功能的逻辑,很多内容可能他根本用不到。这即浪费了用户的时间,也消耗了我们的带宽。

于是,为了解决这些问题,我们可以求助插件式开发。

我根据自身理解,为以后的文章做出一些约定:

  1. 插件主体彼此分离
  2. 主体可以独立存在并完成大部分工作,包括核心任务
  3. 插件必须依附于特定主体,孤立的插件几乎没有用处
  4. 主体实现主要的功能和逻辑,是某款产品的本质属性
  5. 插件实现某些锦上添花的功能和逻辑,对主体起增强作用
  6. 为了满足上面的要素,主体只负责主要逻辑,并且在特定位置留下开放的接口,对具体插件一无所知
  7. 插件知悉主体的绝大部分甚至全部方法、属性、事件
  8. 主体通过配置文件确定加载哪些插件,使用工厂模式创建插件

上面这些是主要思路。因为应用场景不尽相同,具体实现起来肯定千差万别,不过大体结构应该是相似的,只是组合方式不同。接下来,我开始从代码层面上,解析插件模式的做法。

首先我们需要在主体里植入一些类,来支持插件模式。它可能包含以下几个:

  1. PluginManager
    1. 单例
    2. 用来管理插件的加载、构造、销毁,当发生数据交互的时候,model部分也会将数据交给它来过滤和分发
    3. 可能还要显示插件加载的进度
    4. 处理通用错误
    5. createPlugin(pid:String, vo:PluginVO); //通过配置文件里的内容创建插件
    6. getPlugin(pid:String); //取得插件
    7. refreshPluginsData(obj:Object); //更新所有插件的数据
    8. removePlugin(pid:String); //移除插件
    9. destroyPlugin(pid:String); //销毁插件
  2. PluginLoader
    1. 单例
    2. 用来处理插件的加载、卸载过程
    3. loadPlugin(pid:String, vo:PluginVO); //加载插件
    4. unloadPlugin(pid:String); //卸载加载到的插件
  3. PluginVO
    1. 单个插件的数据,如id、类路径、权限等等
    2. 一般由配置文件生成
  4. IPlugin
    1. 插件接口,由PluginManager来处理基础交互
    2. install(vo:PluginVO)  //安装,通知它可以与外界进行交互了
    3. fill(data:Object)  //填充数据,Install之后调用
    4. refresh(data:Object) //更新数据,fill之后需要刷新数据时调用
    5. destroy() //摧毁,确定插件不再需要的时候调用

那些具体的方法可能未必需要,也可能还有些方法未能写全。不过没关系,后面,我将结合实例,讨论插件的具体实现方式。