笔记设计模式5提高代码质量

73次阅读

共计 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);
    }
    }

正文完
 0