前端设计模式笔记|青训营

68 阅读4分钟

前端设计模式

浏览器设计模式

单例模式

定义:全局唯一访问对象
In software engineering, the singleton pattern is a software design patternthat restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.
应用场景:缓存、全局状态管理 1、需要频繁实例化然后销毁的对象。
2、创建对象时耗时过多或者耗资源过多,但又经常用到的对象。
3、有状态的工具类对象。
4、频繁访问数据库或文件的对象
用单例模式实现请求缓存

static getInstance(){
  if(this.instance){
  return this.i;nstance;
  this.instance=new Request();
  return this.instance;
  }
}

事例补充:弹窗、对话框、浮窗之类是使用单例模式

//创建对象的方法传入疯转的getSingle函数
var getSingle=function(fn){
    var result; //这里的result只有在调用时才被创建,所以是惰性单例
    return function(){
        return result || (result=fn.apply(this,arguments)); //控制单例
    }
};
//单一职责,这里就是创建div,getSingle做单例
var createModal=function(){
    var div = document.creatElement('div');
    return div
};
 
var createSingletModal=getSingle(createModal);
 
document.getElementById( 'Btn' ).onclick = function(){ 
 var layer = createSingletModal(); 
 layer.style.display = 'block'; 
}; 

发布订阅模式

定义:一种订阅机制,可在被订阅对象发生变化时通知订阅者。
订阅发布模式(Publish-Subscribe Pattern),又称观察者模式(Observer Pattern),是一种常用的设计模式,用于解决多个对象间的依赖关系,降低系统耦合度,提高代码的复用性和可维护性。 发布订阅是一种消息范式,发布者不会将消息直接发送给订阅者,而是将发布的消息分为不同的类别,这意味着发布者和订阅者不知道彼此的存在。在发布者和订阅者之间存在第三个组件,称为消息代理或调度中心或中间件,它维持着发布者和订阅者之间的联系,过滤所有发布者传入的消息并相应地分发它们给订阅者。订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者存在在订阅发布模式中,存在两类角色:发布者和订阅者。发布者负责向订阅者发送消息,而订阅者则负责接收消息并做出相应的处理。发布者和订阅者之间通过一个中介者(通常称为消息队列或事件总线)来进行通信,发布者发布消息后,消息将被发送到中介者,中介者再将消息分发给所有订阅者。
具体实现上,订阅者需要先订阅发布者感兴趣的事件或主题(Topic),这样才能接收到相应的消息。当发布者发布与该主题相关的消息时,所有订阅该主题的订阅者将收到该消息,并进行相应的处理。

应用场景:从系统架构之间的解耦,到业务中一些实现模式,像邮件订阅,上线订阅等

  1. 应用程序需要向大量消费者广播信息。例如微信订阅号就是一个消费者量庞大的广播平台。
  2. 应用程序需要与一个或多个独立开发的应用程序或服务通信,这些应用程序或服务可能使用不同的平台、编程语言和通信协议。
  3. 应用程序可以向消费者发送信息,而不需要消费者的实时响应。

发布订阅模式与观察者模式对比

观察者模式中,Subject 自己维护观察者列表进行注册和通知。 发布订阅模式的话,引入一个中间平台进行注册和通知,相当于从 Subject 中解耦出来。 观察者通过 on 向 EventBus 注册事件,然后 Subject 通过 emit 向 EventBus 发射事件,由 EventBus 来向观察者更新。

EventBus事例

const observersMap = {}
const listen = function (key, fn) {
    if (!observersMap[key]) {
        observersMap[key] = [];
    }
    observersMap[key].push(fn);
};
const trigger = function () {
    const key = Array.prototype.shift.call(arguments),
        fns = observersMap[key];
    if (!fns || fns.length === 0) {
        return false;
    }
    for (let i = 0, fn; fn = fns[i];i++ ) {
        fn.apply(this, arguments);
    }
};
const remove = function (key, fn) {
    const fns = observersMap[key];
    if (!fns) {
        return false;
    }
    if (!fn) {
        fns && (fns.length = 0) // 全部清空
    } else {
        let findIndex = -1;
        for (let i = 0; i < fns.length; i++) {
            if (fns[i] === fn) {
                findIndex = i;
                break;
            }
        }
        if (findIndex !== -1) {
            fns.splice(findIndex, 1);
        }
    }
};


// 同一种功能可能会见到不同名字,这里都导出去
export const EventBus = {
    listen,
    attach: listen,
    on: listen,

    remove,
    detach: remove,

    trigger,
    emit: trigger,
};