js-原创-《js前端可能会用到的设计模式总结》

参考:
https://blog.csdn.net/sinat_22209293/article/details/79101546
https://www.cnblogs.com/yangguoe/p/8459312.html
https://www.jianshu.com/p/d8c1c426d028
https://www.jianshu.com/p/f0f22398d25d

【一】单例模式
单例模式的定义是保证一个类只有一个实例,并且提供一个访问它的全局访问点。有些时候一些对象我们往往只需要一个,比如线程池、全局缓存、浏览器中的window对象等。单例模式的优点是:

可以用来划分命名空间,减少全局变量的数量
使用单例模式可以使代码组织的更为一致,使代码容易阅读和维护
可以被实例化,且实例化一次

要实现一个标准的单例模式并不复杂,无非是用一个变量标识当前是否已经为某个类创建过对象,如果是,则在下一次获取这个类的实例时,直接返回之前创建的对象。下面是单例模式的基本结构:

// 单例模式
var Singleton = function(name){
    this.name = name;
    this.instance = null;
};
Singleton.prototype.getName = function(){
    return this.name;
};
// 获取实例对象
Singleton.getInstance = function(name) {
    if(!this.instance) {
        this.instance = new Singleton(name);
    }
    return this.instance;
};
// 测试单例模式的实例
var a = Singleton.getInstance("aa");
var b = Singleton.getInstance("bb");

实际上因为单例模式是只实例化一次,所以a和b其实是相等的。也即是说下面语句的值为true。

console.log(a===b);//true

由于单例模式只实例化一次,因此第一次调用,返回的是a实例的对象,继续调用的时候,b的实例也就是a的实例,因此下面打印的都是aa:

console.log(a.getName());// aa
console.log(b.getName());// aa  

【二】工厂模式

function Person(name, age){
    var person = new Object();
    person.name = name;
    person.age = age;
    person.printName = function(){
        console.log(this.name);
    };
    person.printAge = function(){
        console.log(this.age);
    }
    return person;
}

var person = Person('xin',22);

【三】观察者模式

class Subject{
  constructor(){
    this.subs = [];
  }
  addSub(sub){
    this.subs.push(sub);
  }
  notify(){
    this.subs.forEach(sub=> {
      sub.update();
    });
  }
}
//观察者
class Observer{
  update(){
    console.log('update');
  }
}

测试代码:

let subject = new Subject();
let ob = new Observer();
//目标添加观察者了
subject.addSub(ob);
//目标发布消息调用观察者的更新方法了
subject.notify();   //update

可以看到目标和观察者是直接联系在一起的。观察者把自身添加到了目标对象中,可见和发布订阅模式差别还是很大的。在这种模式下,目标更像一个发布者,他让添加进来的所有观察者都执行了update函数,而观察者就像一个订阅者。

观察者模式和发布订阅模式最大的区别就是发布订阅模式有个事件调度中心。

【四】发布订阅模式

var pubsub = (()=>{
  var topics = {};
  function subscribe(topic,fn){
    if(!topics[topic]){
      topics[topic] = [];  
    }
    topics[topic].push(fn);
  }
  function publish(topic,...args){
    if(!topics[topic])
      return;
    for(let fn of topics[topic]){
      fn(...args);  
    }
  }
    return {
      subscribe,
      publish
  }
})();

测试代码:

pubsub.subscribe('test',function(a,b){  //订阅者A订阅了test事件
    console.log(a,b);    
});
pubsub.publish('test','123','HH');   //123  HH(发布者B发布了test事件)

在观察者模式中,观察者需要直接订阅目标事件。在目标发出内容改变的事件后,直接接收事件并作出响应。发布订阅模式相比观察者模式多了个事件通道,订阅者和发布者不是直接关联的。
这段话可以看出上面的例子是发布订阅模式。订阅者A和发布者B是通过pubsub这个对象关联起来的,他们没有直接的交流。

你可能感兴趣的:(js-原创-《js前端可能会用到的设计模式总结》)