首先说明,前端架构代码封装,不是说设计模式,而是封装约定俗成的规矩,这个规矩多半是由编程语言缺点造成的。
1. 使用者和开发者区别
先看例子
class ClassName {
// 开发者的方法名
static _getBase64ByCb (file, cb) {
// todo
}
// 使用者的方法名
getBase64 () {
const file = this.file
let base64 = ''
this._getBase64ByCb(file, function (base64) {
base64 = base64
})
return base64
}
}
// 后续添加的使用者的方法
ClassName.prototype.getBase64s = function () {
const base64s = []
this.files.forEach(file => {
let base64 = ''
ClassName._getBase64ByCb(file, function (base64) {
base64 = base64
})
base64s.push(base64)
})
return base64s
}
从_getBase64ByCb、getBase64、getBase64s三个方法,基本能看出
- 从名字上,能区分谁是开发者使用的,谁是使用者使用的
- 开发者使用的方法是用于后续扩展,如
getBase64s方法一开始没有分装,后续使用者在原有基础上进行扩展。 - 为什么
_getBase64ByCb是静态方法?这里不是静态方法,而是模拟protected属性。
1.1 区别总结:
1> 命名方式体现上
- 开发者使用的方法,关注于执行的过程
- 使用者使用的方法,关注于执行的结果
2> 属性和方法的功能权限不一样
- 开发者使用的方法,有protected、private、$
- 使用者使用的方法,有prototype、static
3> 功能上
- 开发者使用的方法,应用于构建
- 使用者使用的方法,应用于业务(说白点,业务代码抄格式)
2. 对类约定俗成的规矩
Class._fnprotected 保护方法Class._propretyprotected 保护属性Class.prototype._propretyprivate 私有属性,或者只读属性Class.prototype._fn私有方法Class.prototype.$fn框架和第三方插件提供实例化方法Class.prototype.$proprety框架和第三方插件提供实例化属性
这类规定不是那本教科书写着,而是js程序员之间默认规矩。(不了解,无法读源码)
3. 抽象封装和灵活调用是矛盾体
抽象封装和灵活调用是矛盾体,可知封装和灵活要达到平衡,即哪些即封装,根据每个公司的具体的业务能力而定。 这里列举我个人封装的理解,我大部分所做的事情,基本上是业务,也就业务驱动。
- 业务层
- 接口数据,基于纯函数封装
- ui 交互,面向过程
- 脚手架层
- store (本地 storage 处理)
- 接口拦截器,校验登录态(面向用户涉及安全问题,交给后端做,前端检验)
- 路由
- 第三放 js 引用
- 单侧
- 公共组件
第 1 点,这分的好处,在接口变更,ui 交互不改; ui交互更改,接口数据不改;如果数据和ui交互都更改,重构。题外话,这是大多数前端主要工作,当熟练这部工作,需要跳出,不能满足这种螺丝工作。
第 2 点,其实很多脚手架一般都是寻寻渐进,形式不固定,只要能满足 6 点即可,脚手架怎么搭建,那是另外一个大的话题。