Archive for 02月, 2009

基于CakePHP的模块化应用系统设计

和robert讨论WEB系统插件化、模块化设计,虽然大家最终意见都倾向于不对原系统作大的改动,只增加一些开关来实现模块可配置化,但Spark这边还是稍微花了点时间写了一个模块化系统的设计demo。
这个demo是基于CakePHP的插件机制来写的,但CakePHP对于插件间的交互和互操作并没有提供什么机制。先来看一个demo的样子:

这个demo系统有两个模块(CakePHP插件)module1和module2,圆圈的地方是菜单,这里的菜单被设计成可扩展的,每个子模块都可以按自己需要往菜单上添加项。来看看添加菜单的代码:

exts.php文件位于module1的plugin目录下。每个插件目录下都可以有这个文件,并且会在全局app_controller的beforeFilter中被vendors下的extloader.php文件读取。
这里的代码首先判断了module1模块是否被启用,然后声明(export)了两个扩展点,接着对全局的菜单global/menu作了一个扩展。
再来看看在app_controller.php里global menu是如何被构造的:

然后在default.thtml layout里面输出menu的代码即可:

上面基本展示了如果构建一个可扩展的菜单系统。在这个demo中还有一个module1的post查看功能被module2提供的bookmark功能扩展的例子,原理是一样的:

最后来看看vendors/extloader.php是如何工作的:

这里主要是遍历CakePHP的每一个plugin,load其目录下的exts.php文件,并且把每个plugin作为一个模块装入 extloader的Modules数组,在首页我们看到了可以对module是否启用进行配置,因为是demo,所以这里使用了Session作为数据 存储,呵呵。
细心的同学可能会发现其实extloader的export方法根本没什么用,之所以写出来是设想每个export出来的extention point是有一定规范的,可以用一定的数据结构描述出来。这里偷懒就没有去写了!
最后一个特性,在命令行下试试下面的操作:
cd app/plugins
mv module2 ../
再刷新页面看看,module2的菜单以及module1 post operations里的bookmark button是不是没了?真正的可插拨哦,呵呵!
demo的代码下载:extphp.zip

FireStats icon Powered by FireStats MC Inside