设计模式

最后更新于:2022-04-02 03:27:43

[TOC] ## 适配器 可用于对新老数据的转换兼容 ``` const arr = ['Javascript', 'book', '前端编程语言', '8月1日'] function arr2objAdapter(arr) { // 转化成我们需要的数据结构 return { name: arr[0], type: arr[1], title: arr[2], time: arr[3] } } const adapterData = arr2objAdapter(arr) ``` ## 单例模式 ``` // 创建弹框方法 const createLoginLayer = function() { const div = document.createElement('div') div.innerHTML = '登入浮框' div.style.display = 'none' document.body.appendChild(div) return div } // 使单例模式和创建弹框代码解耦 // 创建单例模式 const getSingle = function(fn) { const result return function() { return result || result = fn.apply(this, arguments) } } const createSingleLoginLayer = getSingle(createLoginLayer) document.getElementById('loginBtn').onclick = function() { createSingleLoginLayer() } ``` ## 代理模式 > 代理模式的定义:为一个对象提供一个代用品或占位符,以便控制对它的访问。 ### 虚拟代理 实现图片预加载 ``` const myImage = (function() { const imgNode = document.createElement('img') document.body.appendChild(imgNode) return { setSrc: function(src) { imgNode.src = src } } })() const proxyImage = (function() { const img = new Image() img.onload = function() { // http 图片加载完毕后才会执行 myImage.setSrc(this.src) } return { setSrc: function(src) { myImage.setSrc('loading.jpg') // 本地 loading 图片 img.src = src } } })() proxyImage.setSrc('http://loaded.jpg') ``` ### 缓存代理 ``` const demo =function (a,b) { return a+b } const proxy =(function () { const cached={} return function (a,b) { let cached_key =[].slice.call(arguments).toString() if (cached[cached_key]) { console.log("access cache"); return cached[cached_key] }else{ console.log("no access cache"); cached[cached_key]=demo(a,b) return cached[cached_key] } } })() console.log(proxy(1,2)); console.log(proxy(2,2));//第二次缓存 console.log(proxy(2,2));//第二次缓存 ``` 任意函数的缓存代理 ``` const demo =function (a,b) { return a+b } const proxy =function (func) { const cached={} return function (a,b) { let cached_key =[].slice.call(arguments).toString() if (cached[cached_key]) { console.log("access cache"); return cached[cached_key] }else{ console.log("no access cache"); cached[cached_key]=func(a,b) return cached[cached_key] } } } const proxyCache=proxy(demo) console.log(proxyCache(1,2)); console.log(proxyCache(2,2));//第二次缓存 console.log(proxyCache(2,2));//第二次缓存 console.log(proxyCache(2,2));//第二次缓存 ``` ## 订阅发布模式 ``` class Event { constructor() { // 所有 eventType 监听器回调函数(数组) this.listeners = {} } /** * 订阅事件 * @param {String} eventType 事件类型 * @param {Function} listener 订阅后发布动作触发的回调函数,参数为发布的数据 */ on(eventType, listener) { if (!this.listeners[eventType]) { this.listeners[eventType] = [] } this.listeners[eventType].push(listener) } /** * 发布事件 * @param {String} eventType 事件类型 * @param {Any} data 发布的内容 */ emit(eventType, data) { const callbacks = this.listeners[eventType] if (callbacks) { callbacks.forEach((c) => { c(data) }) } } } const event = new Event() event.on('open', (data) => { console.log("ouput :",data) }) event.emit('open', { open: true }) ``` ## 观察者模式 > **观察者模式**定义了一种一对多的依赖关系,让多个**观察者**对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有**观察者**对象,使它们能够自动更新 ```


``` ## 装饰者模式 > 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。 ``` class A { getContent() { return '第一行内容' } render() { console.log(this.getContent()); } } function decoratorOne(cla) { const prevGetContent = cla.prototype.getContent cla.prototype.getContent = function() { console.log("这是输出前需要操作的内容"); return prevGetContent() } return cla } const B = decoratorOne(A) new B().render() /** output 这是输出前需要操作的内容 第一行内容 */ ``` ## 策略模式 ``` function getYearEndBonus(strategyFn) { if (!strategyFn) { return {} } return strategyFn() } const bonusStrategy = { A() { return { bonus: 50000, prize: 'mac pro', } }, B() { return { bonus: 40000, prize: 'mac air', } }, C() { return { bonus: 20000, prize: 'iphone xr', } }, D() { return { bonus: 10000, prize: 'ipad mini', } }, } const performanceLevel = 'A' getYearEndBonus(bonusStrategy[performanceLevel]) ``` ## 职责链模式 ``` function order(options) { return { next: (callback) => callback(options), } } function order500(options) { const { orderType, pay } = options if (orderType === 1 && pay === true) { console.log('500 元定金预购, 得到 100 元优惠券') return { next: () => {}, } } else { return { next: (callback) => callback(options), } } } function order200(options) { const { orderType, pay } = options if (orderType === 2 && pay === true) { console.log('200 元定金预购, 得到 50 元优惠券') return { next: () => {}, } } else { return { next: (callback) => callback(options), } } } function orderCommon(options) { const { orderType, stock } = options if (orderType === 3 && stock > 0) { console.log('普通购买, 无优惠券') return {} } else { console.log('库存不够, 无法购买') } } order({ orderType: 1, pay: true, stock: 500, }).next(order500) .next(order200) .next(orderCommon) ```
';