几种常见的设计模式

2020-11-19  本文已影响0人  王二麻子88

学习程序设计模式

1. 单例设计模式

过于简单无脑, 就是依靠类中的静态属性

2. 观察者模式 (Observe)

观察者实际上是Map集合的巧用

class Observe {
  constructor() {
    this.evenList = {};
  }
  addEvent(type, callBack) {
    if (!this.evenList[type]) {
      this.evenList[type] = []
    }
    this.evenList[type].push(callBack);
  }
  removeEvent(type, callBack) {
    if (!this.evenList[type]) {
      throw new Error("no bind such "+ type + " event")
    } else {
      if (!callBack) {
        this.evenList[type] = [];
      }
      this.evenList[type].forEach((item, index) => {
        if (item === callBack) {
          this.evenList[type].splice(index, 1);
        }
      })
    }
  }
  emit(type) {
    if (this.evenList[type]) {
      this.evenList[type].forEach(item => item())
    }
  }
}

const o1 = new Observe();
o1.addEvent("left", function () {
  console.log("left1");
});
o1.addEvent("left", left2);
function left2 () {
  console.log("left2");
}
o1.addEvent("left", function () {
  console.log("left3")
});
o1.addEvent("right", function () {
  console.log("right1");
});
o1.removeEvent("left", left2);
o1.emit("left");

3. 代理模式

对目标方法的进一层封装

// 代理模式

// 图片懒加载 --> 使用闭包防止变量污染, 返回 设置url 的方法对象
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() {
    myImage.setSrc(this.src)
  };
  return {
    setSrc: function(src) {
      console.log('src', src);
      myImage.setSrc(src);
      img.src = src;
    }
  }
})();
// 在实际使用的过程中, 不直接使用目标函数或者方法, 而是使用代理对象-->由代理对象指定使用的方法
proxyImage.setSrc('http://webSize/websSizeImage.jpg');

4. 迭代器模式

关于虚拟指针位移的使用

const Iterator = function (obj) {
  let current = 0;
  let next = function () {
    current++;
  };
  let isFinish = function () {
    return !!(current > obj.length || current === obj.length)
  };
  const getCurrentItem = function () {
    return obj[current];
  };
  const getCurrent = function () {
    return current
  };
  const resetCurrent = function () {
    current = 0
  };
  return {
    next,
    isFinish,
    getCurrentItem,
    getCurrent,
    resetCurrent
  }
};

let iteratorArray1 = [1, 2, 3, 4, 5];
let iteratorArray2 = [1, 2, 3, 4, 5];
let iteratorArray3 = [2, 2, 3, 5, 4];
function compara(Array1, Array2) {

  console.log("index: "+ Array1.getCurrent());
  console.log("index: "+ Array2.getCurrent());
  while (!Array1.isFinish() && !Array2.isFinish()) {
    console.log(Array1.getCurrentItem());
    console.log(Array2.getCurrentItem());
    console.log("index: "+ Array1.getCurrent());
    console.log("index: "+ Array2.getCurrent());
    if (Array1.getCurrentItem() !== Array2.getCurrentItem()) {
      // throw new Error("not quail value");
      Array1.resetCurrent();
      Array2.resetCurrent();
      return false;
    }
    Array1.next();
    Array2.next();
  }
  Array1.resetCurrent();
  Array2.resetCurrent();
  return true
}
iteratorArray1 = Iterator(iteratorArray1);
iteratorArray2 = Iterator(iteratorArray2);
iteratorArray3 = Iterator(iteratorArray3);
console.log(compara(iteratorArray1, iteratorArray2));  // true
console.log(compara(iteratorArray1, iteratorArray3));  // false

5. 职责链模式

类似于实现 jQuery的链式调用

function currentEnvCanUseHTML5Form() {
  return true
}
function runHTML5Form(obj) {
  console.log("runHTML5Form");
  console.log(obj);
  return "runHTML5Form";
}
function currentEnvCanUseFlash() {
  return false
}
function runFlash(obj) {
  console.log("runFlash");
  console.log(obj);
  return "runFlash"
}

function useHTML5Form(obj) {
  if (currentEnvCanUseHTML5Form()) {
    return runHTML5Form(obj)
  }
  return "next"
}

function useFlash(obj) {
  if (currentEnvCanUseFlash()) {
    // 当前支持 flash
    return runFlash(obj)
  }
  return "next"
}


function createChain() {
  Function.prototype.chain = function (nextFn) {
    const that = this;
    return function () {
      let result = that.apply(this, arguments);
      if (result === "next") {
        return nextFn.apply(this, arguments)
      }
      return ""
    }
  }
}
createChain();
var upload = useFlash.chain(useHTML5Form);

upload({info: "info"});

6. 策略模式

对多重判断从主逻辑中的脱离

const strategies = {
  "2": function (salary) {
    return salary * 2
  },
  "3": function (salary) {
    return salary * 3
  },
  "4": function (salary) {
    return salary * 4
  }
};

const calculateBonus = function (level, salary) {
  return strategies[level](salary);
};

console.log(calculateBonus("2", 1200));

番外

1. 关于闭包避免全局污染变量

var user = (function() {
  var name = "wang";
  return {
    getName: function() {
      console.log(name);
      return name
    }
  }
})();
console.log(user.getName());
上一篇 下一篇

猜你喜欢

热点阅读