考虑一个允许插件对其程序流做出反应的应用。
我知道两种方法可以实现:钩子和事件
1.挂钩
在主程序流中使用调用来清空函数。插件可以覆盖这些功能。
例如,Drupal CMS实现了可用于模块和主题的挂钩。这是在file_copy函数中如何实现钩子的示例。
function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
// ... [File copying routine]
// Inform modules that the file has been copied.
module_invoke_all('file_copy', $file, $source);
return $file;
// ...
}
模块可以实现modulename_file_copy($file, $source)
将由module_invoke_all
in 调用的功能file_copy
。该功能完成后,file_copy
将恢复执行。
2.活动
拥有应用程序分发事件,插件可以监听该事件。收到已订阅的事件后,插件将拦截程序流并执行必要的操作。
例如,一个jQuery画廊插件Fotorama 实现了几个事件。例如,这show
是触发fotorama:show
事件的方法的一部分。
that.show = function (options) {
// ... [show the new frame]
// [fire the event]
options.reset || triggerEvent('show', {
user: options.user,
time: time
});
// ... [do lots of other stuff with navigation bars, etc.]
};
脚本可以侦听此事件,并在触发时执行以下操作:
$('.fotorama').on(
'fotorama:show',
function (e, fotorama, extra) {
console.log(e.type + (extra.user ? ' after user’s touch' : ''));
console.log('transition duration: ' + extra.time);
}
);
题
还有其他主流方式来实现这种插件行为吗?
如果不是,何时应使用钩子,何时应使用事件?从应用程序和插件开发人员的角度来看,考虑最终目标是使代码更具可维护性和可读性吗?