架构本质
- 微内核架构是一种软件架构模式。在 JavaScript 应用中,微内核主要关注的是系统的核心部分尽可能小而简单,它将一些基本的功能如系统启动、模块加载等放在内核中。其他功能以插件或模块的形式挂载在微内核上。例如,在一个复杂的前端框架中,微内核可能只负责处理最基本的组件渲染逻辑和事件循环,而像路由、状态管理等高级功能则是通过插件添加进来的。
- 这种架构的优点是可扩展性强,内核相对稳定,方便对系统进行功能扩展和维护,各个插件可以独立开发、测试和部署。
场景
- 应用场景主要是在构建大型复杂系统时,如大型前端应用框架或者后端服务框架。目的是为了将系统解耦,让系统的各个部分可以独立演进,同时保持核心的稳定性。比如在开发一个跨平台的移动应用框架时,微内核可以处理底层的设备交互和基本的 UI 渲染逻辑,而针对不同平台的特性(如安卓和 iOS)可以通过插件来实现。
搞个简单的demo
- tips: 设计落地可具体,但是思想要抽象,以下实现只是一只具体方式,思维不要受限于某种具体实现方式
dir
--kernel.js
--main.js
--package.json
--reversePlugin.js
--uppercasePlugin.js
kernel.js
- 微内核核心类
// 定义事件中心,用于插件之间的通信
const eventCenter = {
events: {},
// 订阅事件
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
},
// 触发事件
emit(eventName,...args) {
const callbacks = this.events[eventName];
if (callbacks) {
callbacks.forEach(callback => callback(...args));
}
}
};
class MicroCore{
constructor(options={}){
this.options=options||{}
this.core(this.options);
}
options = {}
plugins = [];//插件列表
resMap = {};//存放插件处理结果
text=""
count = 0;
core(options){
console.log('核心逻辑')
}
init(plugin){
// 调用插件的初始化函数,注册事件到事件中心
const eventName=plugin.name;
eventCenter.on(eventName, (text) => {
//防止多次调用start重复派发
if(this.count>=this.plugins.length)return;
this.count+=1;
//取下一个插件执行
const nextPlugin = this.plugins[this.count];
plugin.process(text);
//记录插件处理完的结果
this.resMap[plugin.name] = plugin.text;
this.text = plugin.text;
if(!nextPlugin){
eventCenter.emit('app:end', this.text);
}
else{
eventCenter.emit(nextPlugin.name, plugin.text);
}
});
}
// 加载插件函数
loadPlugin(plugin) {
this.plugins.push(plugin);
this.init(plugin);
}
// 模拟微内核启动,加载插件并触发初始化事件
start(text) {
//订阅事件执行完毕
eventCenter.on('app:end',(text)=>{
console.log('options',this.options);
this.options.end.call(this,text);
})
eventCenter.emit(this.plugins[0].name, text);
}
}
// 对外暴露接口
export {
MicroCore,
eventCenter
};
main.js
- 入口文件
import { MicroCore } from './kernel.js';
import uppercasePlugin from './uppercasePlugin.js';
import reversePlugin from './reversePlugin.js';
const microCore=new MicroCore({
end(text){
//所有插件执行完毕会执行的回调
console.log('log=>this',text);
}
});
// 加载插件到微内核
microCore.loadPlugin(reversePlugin);
microCore.loadPlugin(uppercasePlugin);
const originalText = 'hello world';
// 启动微内核
microCore.start(originalText);
package.json
// 工程化配置
{
"scripts":{
"serve": "node main.js"
},
"name": "project-demo",
"type": "module"
}
reversePlugin.js
- 插件1
export default {
name:'reversePlugin',
text: '',
process(text) {
this.text = text;
// 反转文本
this.text = this.text.split('').reverse().join('');
// 触发最终文本处理完成的事件,并传递最终处理后的文本
this.start();
},
start() {
console.log('开始执行倒序');
}
};
uppercasePlugin.js
- 插件2
export default {
name: 'uppercasePlugin',
text: '',
process(text) {
this.text = text;
// 将文本转换为大写
this.text = this.text.toUpperCase();
this.start();
},
start() {
console.log('开始执行转大写');
}
};
run
npm run serve
console.log↓
核心逻辑
开始执行倒序
开始执行转大写
options { end: [Function: end] }
log=>this DLROW OLLEH
总结
至此,一个简易demo完成,核心逻辑在类里完成,其他功能可以通过插件的方式添加或者移除,减少耦合