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这个对象关联起来的,他们没有直接的交流。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 设计模式 单例 单例模式的核心思想是让指定的类只存在唯一一个实例。这意味着当你第二次使用相同的类去创建对象的时候,...
    代码上的蚂蚁阅读 515评论 0 0
  • javascript设计模式与开发实践 设计模式 每个设计模式我们需要从三点问题入手: 定义 作用 用法与实现 单...
    穿牛仔裤的蚊子阅读 4,296评论 0 13
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,932评论 2 17
  • 工厂模式 单体模式 模块模式 代理模式 职责链模式 命令模式 模板方法模式 策略模式 发布-订阅模式 中介者模式 ...
    HelloJames阅读 1,028评论 0 6
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,161评论 1 32