设计原则
开放封闭原则 OCP 对扩展开放 对修改封闭
工厂模式
简单工厂模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Man { constructor(name) { this.name = name } alertName() { alert(this.name) } }
class Factory { public static create(name): Man { return new Man(name) } }
Factory.create('Bobo').alertName()
|
- 工厂模式并不仅仅是用来 new 出实例
- 隐藏创建实例的复杂度,只需提供一个接口,传递对应的参数,就可返回实例;至于这些参数怎么使用,内部有什么逻辑并不关心
- Vue
createComponent
创建异步组件
- React
createElement('div', {}, children)
生成 vnode
单例模式
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Singleton { constructor() {} }
Singleton.getInstance = (function() { let instance return function() { if (!instance) { instance = new Singleton() } return instance } })()
|
- 全局缓存
- 全局状态管理 Vuex
- 全局 loading dialog
- 购物车 数据库连接
适配器模式
适配器用来解决两个接口不兼容的情况,不需要改变已有的接口,通过包装一层的方式实现两个接口的正常协作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Plug { getName() { return '港版插头' } }
class Target { constructor() { this.plug = new Plug() } getName() { return this.plug.getName() + ' 适配器转二脚插头' } }
let target = new Target() target.getName()
|
- computed 计算属性 时间戳转日期 这一过程
不改变已有接口,给对象添加功能
面向切面编程 AOP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| function logDec(target) { target.flag = true }
function readonly(target, name, descriptor) { descriptor.writable = false return descriptor }
function log(target, name, descriptor) { const value = descriptor.value descriptor.value = function(param) { console.log(`Calling ${name} with `, param) return value.call(this, param) } return descriptor }
@logDec class Test { @readonly name = 'Bobo'
@log public fn(param) { } }
let t = new Test()
console.log(Log.flag)
t.name = 'daidaibo'
|
代理模式
不让外部直接访问到对象
1 2 3
| new Proxy
Object.defineProperty
|
观察者模式
1 2 3
| btn.addEventListener('click', () => { })
|
- Subject 和 Observer 直接绑定,中间无媒介
addEventListener
事件监听
发布订阅模式
- Publisher 和 Observer 解藕,中间有媒介
EventBus
自定义事件
- Vue 响应式 依赖收集 派发更新
外观模式
1 2 3 4 5 6 7 8 9
| function addEvent(elem, evType, fn, useCapture) { if (elem.addEventListener) { elem.addEventListener(evType, fn, useCapture) } else if (elem.attachEvent) { elem.attachEvent('on' + evType, fn) } else { elem['on' + evType] = fn } }
|
迭代器模式
1 2 3 4 5 6 7 8 9 10
| obj[Symbol.iterator] = function () { return { next() { return { value, done: true } } } }
|