vue2 源码中的设计模式, 有观察者模式, 模板方法模式等

文章目录

  • ​​1.单例模式​​
  • ​​2.策略模式​​
  • ​​3.工厂模式​​
  • ​​4.装饰器模式​​
  • ​​5.观察者模式​​
  • ​​6.模版模式​​
  • ​​7.适配器模式​​
  • ​​8.高阶函数​​

1.单例模式

function Single () {
if (!Single.instance) {
Single.instance = this;
}
return Single.instance
}
const a = new Single()
const b = new Single()
// a === b; true

2.策略模式

const obj = {
a: function() {},
b: function() {}
}

const fn = (target) => {
return (key) => target[key]()
}
const geta = fn(obj)('a');
const getb = fn(obj)('b');

3.工厂模式

var myApp = {};
myApp.dom = {};
myApp.dom.text = function(url) {
this.url = url;
this.insert = function(dom) {
const text = document.createTextNode(this.url);
dom.appendChild(text);
}
}
myApp.dom.img = function(url) {
this.url = url;
this.insert = function(dom) {
const img = document.createElement('image');
img.src = this.url;
dom.appendChild(img);
}
}
const textObj = new myApp.dom.text('http://www.learn.wmcweb.cn');
textObj.insert(document.body);

const imgObj = new myApp.dom.img('http://www.learn.wmcweb.cn')
imgObj.insert(document.body);

我们可以通过一个中间函数,通过形参去确定哪个对象

myApp.dom.factor = function(type, url) {
return new myApp.dom[type](url)
}
const imgfator = myApp.dom.factor('img', 'http://www.learn.wmcweb.cn')
const textFator = myApp.dom.factor('text', 'http://www.learn.wmcweb.cn')
imgfator.insert(document.body);
textFator.insert(document.body)

4.装饰器模式

var person = {};
person.say = function() {
this.nowTime = function() {
console.log('nowTime');
}
}
person.sleep = function() {
this.curentTime = function() {
console.log('this is current time');
}
}
person.getFn = function(type) {
person[type].prototype = this;
return new person[type]
}
person = person.getFn('say');

console.log(person.nowTime()) // ok
console.log(person.curentTime()) // 报错

5.观察者模式

发布对象:重要事情发生时,会通知订阅者

订阅对象:监听发布对象的通知,并做出相应的反应

观察者主要分为两类:​​推送模式和拉动模式​

推送模式是由发布者负责将消息发送给订阅者

拉动模式是订阅者主动跟踪发布者的状态变化

var observer = {};
observer.list = []; // 存放订阅者的回调函数

// 创建发布者
observer.trigger = function() {
this.list.forEach(fn => {
fn.apply(this, arguments)
})
}
// 创建订阅者
observer.addLinsten = function(fn) {
this.list.push(fn)
}

observer.addLinsten(function(week, msg) {
console.log(`今天${week}, ${msg}`)
})
observer.addLinsten(function(week, msg) {
console.log(`今天${week}, ${msg}`)
})

observer.trigger('周末', '不上班')
命令模式

var btnClick = function(btn,callback) {
btn.onclick = callback;
}
const modal = {
open: function() {
console.log('open');
},
close: function() {
console.log('close');
}
}
btnClick(document.getElementById('app'), modal.open)
btnClick(document.getElementById('app'), modal.close)

6.模版模式

var Table = function() {}
Table.prototype.drawHeader = function() {}
Table.prototype.drawBody = function() {}
Table.prototype.init = function() {
this.drawHeader();
this.drawBody();
}
const createTable = new Table();
createTable.init();

子类扩展

var subTable = function() {}
subTable.prototype = new Table();
const stable = new subTable();
stable.init();

7.适配器模式

const render = (obj) => {
obj.start();
}
const airplane = {
start() {
console.log('飞机开始飞了')
}
}
const car = {
start() {
console.log('火车开始了');
}
}

render(airplane)
render(car)

8.高阶函数

Function.prototype.before = function(beforeFn) {
const self = this;
return function() {
beforeFn.apply(this, arguments);// 先执行回调函数
return self.apply(this, arguments) // 然后执行原函数
}
}
Function.prototype.after = function(afterFn) {
const self = this;
return function() {
const ret = self.apply(this, arguments);
afterFn.apply(this, arguments); // 执行当前的回调函数
return ret;
}
}
var func = function () {
console.log(2)
}
func = func.before(()=> {
console.log(1)
}).after(() => {
console.log(3)
});
func(); // 1,2,3