共计 2597 个字符,预计需要花费 7 分钟才能阅读完成。
策略模式 / 状态模式
- 目的:优化 if-else 分支
- 应用场景:当代码 if-else 分支过多时
-
基本结构
// 计算器,将 if 判断用策略模式改写 function calculator(type, a, b) { var strategy = {add(a, b) {return a + b}, minus(a, b) {return a - b}, division(a, b) {return a / b} } return strategy[type](a, b) } // 状态模式 function stateFactor (state) { var stateObject = { _status: '', state: {state1 () {}, state2 () {} }, run () {return this.state[this._status]()} } stateObject._status = state return stateObject } stateFactor('state1').run()
-
例:复合运动
function moveLeft() {console.log('left') } function moveRight() {console.log('right') } function moveTop() {console.log('top') } function moveBottom() {console.log('bottom') } function move() {this.status = []; this.actionHandle = { left: moveLeft, right: moveRight, top: moveTop, bottom: moveBottom } } move.prototype.run = function () { // 将 arguments 变成真数组 this.status = Array.prototype.slice.call(arguments); this.status.forEach((action) => {this.actionHandle[action]();}) } new move().run('left', 'right');
外观模式
- 目的:给多个复杂的子系统提供一个一致的接口
- 应用场景:完成一个操作需要操作多个子系统
-
基本结构
function Model1 () {} function Model2 () {} function use() {Model2(Model1()) }
迭代器模式
- 目的:不访问内部的情况下,方便的遍历数据
- 应用场景:操作某个对象,不能暴露内部时
-
基本结构 forEach
function Iterator(data) {this.data = data;} Iterator.prototype.dealEach = function (fn) {if (this.data instanceof Array) { // 数组 for (var i = 0; i < this.data.length; i++) {fn(this.data[i], i) } } else { // 对象 for (var item in this.data) {fn(this.data[item], item) } } }
-
例:封装一个筛选数据的方法
var data = [{num: 1}, {num: 2}, {num: 3}] function getData(data) {function Iterator(data) {this.data = data;} Iterator.prototype.hasSomeData = function (handler, num) {var _arr = []; var handleFn; if (typeof handler == 'function') {handleFn = handler;} else {handleFn = function (item) {if (item[handler] == num) {return item;} } } for (var i = 0; i < this.data.length; i++) {var _result = handleFn.call(this, this.data[i]) if (_result) {_arr.push(_result); } } return _arr; } return new Iterator(data); } // 传入属性和值,检测有没有 num 值为 1 的数据 // let r = getData(data).hasSomeData('num', 1); // 传入函数,检测有没有通过函数检测的数据 let r = getData(data).hasSomeData(function (item) {if (item.num - 1 == 2) {return item;} }); console.log(r)
备忘录模式
- 目的:记录状态,方便回滚
- 应用场景:系统状态多样,需要回滚状态
-
基本结构
function memento () {var cache = {} return function (cacheName) {if (cache[cacheName]) {// 有缓存} else {// 没有缓存} } } var mementoFn = memento() mementoFn('xxx')
-
例:前进后退功能
function moveDiv() {this.stateList = []; // 存储状态 this.nowState = 0; // 当前状态 } moveDiv.prototype.move = function (type, num) {moveDiv(type, num); this.stateList.push({ type: type, num: num }); this.nowState = this.stateList.length - 1; } moveDiv.prototype.go = function () { var _state; if (this.nowState < this.stateList.length - 1) { this.nowState++; _state = this.stateList[this.nowState]; moveDiv(_state.type, _state.num); } } moveDiv.prototype.back = function () { var _state; if (this.nowState >= 0) { this.nowState--; _state = this.stateList[this.nowState]; moveDiv(_state.type, _state.num); } }
正文完