基于web/h5应用的插件/扩展方案设计
本文是一个系列文章,谈谈如何降低应用的复杂度,增加可维护性。 文章里面提供的是一种思路,并根据此思路进行实现,将遇到的问题进行解决。
背景
随着用户体量的增加,功能会越来越多,系统会越来越庞大,基于后端的微服务越来越大火,前端层面更多的关注vue,react之类的框架上, 他们解决的是视图和数据的分离,但业务层面的框架或者思想的分享则不多,毕竟偏离了技术的路线。
思想
类似与微信与小程序,浏览器与扩展,或者操作系统与应用程序之间的关系,都是面向开发者的服务(如果客户没有开发能力,也可以根据情况由我方开发者开发)
实现
根据我们自身业务系统的特性,找到我们系统本身独特的,核心的业务性的东西,以此为主线,将各个业务模块或者通用服务抽离。 上面讲的有些抽象,让我们来举几个具体的例子。
假如我们的系统是iconfont.cn
需求: 我的职业是写PPT,每天会高频词找图标放入PPT,它只有复制svg的功能,没有直接复制图片的功能,我不想每次都下载PNG,
我期望有个复制图片的功能,类似于下图
代码方案设计,以下为伪代码,实际生产环境不会这样写,但这不重要,在此,只是提供一种思路给大家。
- 基础功能里将按钮设计成一个数组
- 我们初始化会获取当前用户的扩展并执行(利用
new Function(),后续文章我会详细说明如何设计) - 动态扩展获取到btnGroup,并追加进一个按钮。(这里的难点是如何获取btnGroup,我们不可能将btnGroup设置为全局变量,这样不符合我们的初衷,这里需要我们在设计之初就想好,框架不同,方案不同,后续的文章,我会针对ES5,ES6,Vue等出针对性的写法方案)
我们打包后的部分代码片段如下
//我们系统的基础功能
const btnGroup=[{
name:"SAG 下载",
fn(){}
}];
通过接口获取到的代码片段(此代码片段由用户或管理员上传至我方数据库,并经过接口返回至客户端)
//动态扩展,用户自己上传或者我们分配的扩展
btnGroup.push({
name:"复制 PNG",
fn(){/*具体的实现*/}
})
结束,完成一个简单的功能。
优点
- 功能独立出去了,系统的代码量会变小很对,我们对系统减负,开发员将关注点放在基础功能上,而不是这种定制功能。
- 系统架构清晰,维护起来就容易。
- 需求的响应速度加快,一个功能从提出到用户实际得到,如果用户自己有开发能力,时间等于他自己的开发时间,如果用户没有开发能力,时间等于传达耗时+我方开发员的开发时间。
- 翻车也不怕,如果功能有问题,第一,它只影响使用它的用户,第二,用户或者管理员后台直接设置为无效,即可完美脱离扩展,不影响其他功能,待改进后启用即可。
- 不但可以加功能,还可以打补丁,如漏洞,bug等,完美避开版本控制,领导的最爱。
- 其他的一些好处-_-...
缺点
- 基础代码需要留出一些钩子,以便扩展在合适的时机去执行特定的功能。
- 因扩展是直接运行在浏览器上,es6架构下,代码压缩后,扩展执行需要开发员对webpack和babel的一些打包策略及原理比较熟悉。
- 扩展变多,会不会相互影响,以及更改基础功能后,受影响的扩展如何解决,有待一套完美的方案。
- 千人千面系统管理起来不知道费劲不,权限控制可能有点麻烦。
总结
好处肯定大于坏处,谁用谁知道,我经过实测,效果极佳。
下一篇
基于web/h5应用的插件/扩展/业务剥离方案设计(第二篇 ECMA5.1方案)
结束语:欢迎在评论区交流,如果觉得不错,可以点赞和收藏,持续更新。
博客中标注原创的文章,版权归原作者 苦中作乐才是人生巅峰所有;转载或者引用本文内容请注明来源及原作者;