返回

代码实现:破解JavaScript中单例模式、观察者模式、代理模式等常用设计模式的精髓

见解分享

在JavaScript的世界里,设计模式是一门必不可少的知识,它为我们提供了构建可重用、可维护的代码的利器。JavaScript设计模式是指一套被证明行之有效的代码组织和结构方式,可以帮助我们应对各种常见的编程问题。

本文将带领大家深入探讨JavaScript设计模式的精髓,帮助你理解并运用这些设计模式来编写更优美、更可维护的代码,显著提升代码质量和可重用性。

1. 单例模式

单例模式是一种非常常见的模式,单例模式的定义是:保证一个类仅有一个实例,并提供一个可以访问它的全局访问点。

单例模式多用于唯一弹窗,全局加载条,绑定回调等等。以下是常见实现单例模式的方法:

  • 立即执行函数表达式(IIFE) :这是最简单的方法,通过立即执行一个函数来创建单例对象。
const Singleton = (function() {
  let instance;

  function createInstance() {
    const object = new Object();
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

// 使用单例对象
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true
  • 闭包 :闭包可以用来创建私有变量和方法,从而实现单例模式。
function Singleton() {
  let instance;

  function createInstance() {
    const object = new Object();
    return object;
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
}

const singleton = Singleton();

// 使用单例对象
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();

console.log(instance1 === instance2); // true

2. 观察者模式

观察者模式是一种设计模式,它允许对象在不了解其他对象的情况下依赖于其他对象,从而实现松耦合。

观察者模式经常用于事件处理,例如,当用户点击按钮时,按钮可以通知所有注册的观察者,观察者可以相应地做出反应。以下是常见实现观察者模式的方法:

  • 发布订阅模式 :发布订阅模式是观察者模式的一种常见实现方式,它允许对象通过订阅和发布消息来进行通信。
// 定义一个发布者对象
class Publisher {
  constructor() {
    this.subscribers = [];
  }

  subscribe(subscriber) {
    this.subscribers.push(subscriber);
  }

  unsubscribe(subscriber) {
    const index = this.subscribers.indexOf(subscriber);
    if (index > -1) {
      this.subscribers.splice(index, 1);
    }
  }

  notifySubscribers() {
    this.subscribers.forEach(subscriber => subscriber());
  }
}

// 定义一个观察者对象
class Subscriber {
  constructor(name) {
    this.name = name;
  }

  update() {
    console.log(`${this.name} received a notification!`);
  }
}

// 创建发布者对象
const publisher = new Publisher();

// 创建观察者对象
const subscriber1 = new Subscriber("John");
const subscriber2 = new Subscriber("Mary");

// 观察者订阅发布者
publisher.subscribe(subscriber1);
publisher.subscribe(subscriber2);

// 发布者通知观察者
publisher.notifySubscribers();
  • 事件监听器 :事件监听器也是观察者模式的一种实现方式,它允许对象通过监听事件来做出反应。
// 定义一个对象
const object = {
  count: 0,

  // 订阅事件
  subscribe: function(listener) {
    this.listeners.push(listener);
  },

  // 发布事件
  publish: function() {
    this.count++;
    this.listeners.forEach(listener => listener(this.count));
  }
};

// 定义一个监听器
const listener = function(count) {
  console.log(`The count is now ${count}!`);
};

// 订阅事件
object.subscribe(listener);

// 发布事件
object.publish();
object.publish();
object.publish();

3. 代理模式

代理模式是一种设计模式,它允许一个对象代表另一个对象,从而控制对该对象的访问。

代理模式经常用于以下场景:

  • 访问控制 :代理对象可以控制对真实对象的访问,例如,只能允许某些用户访问某些资源。
  • 缓存 :代理对象可以缓存真实对象的数据,从而提高性能。
  • 日志记录 :代理对象可以记录对真实对象的调用,从而便于调试和分析。

以下是常见实现代理模式的方法:

  • 简单的代理对象 :简单的代理对象直接将对自己的调用转发给真实对象。
// 定义一个代理对象
const proxy = {
  method: function() {
    return realObject.method();
  }
};

// 定义一个真实对象
const realObject = {
  method: function() {
    console.log("Real object method called!");
  }
};

// 使用代理对象
proxy.method(); // Real object method called!
  • 虚拟代理对象 :虚拟代理对象在第一次调用时才创建真实对象,从而延迟了真实对象的创建。
// 定义一个虚拟代理对象
const proxy = {
  method: function() {
    if (!this.realObject) {
      this.realObject = new RealObject();
    }
    return this.realObject.method();
  }
};

// 定义一个真实对象
const RealObject = function() {
  this.method = function() {
    console.log("Real object method called!");
  };
};

// 使用虚拟代理对象
proxy.method(); // Real object method called!

4. 工厂模式

工厂模式是一种设计模式,它允许我们创建对象而不指定其具体类。

工厂模式经常用于以下场景:

  • 创建复杂对象 :工厂模式可以帮助我们创建复杂的对象,而无需了解其内部细节。
  • 解耦 :工厂模式可以将对象的创建和使用解耦,从而提高代码的可维护性。

以下是常见实现工厂模式的方法:

  • 简单工厂模式 :简单工厂模式是一个最简单的工厂模式,它通过一个工厂方法来创建对象。
// 定义一个工厂方法
const factoryMethod = function(type) {
  switch (type) {
    case "A":
      return new ProductA();
    case "B":
      return new ProductB();
    default:
      return null;
  }
};

// 使用工厂方法创建对象
const productA = factoryMethod("A");
const productB = factoryMethod("B");

console.log(productA); // ProductA {}
console.log(productB); // ProductB {}
  • 工厂类模式 :工厂类模式通过一个工厂类来创建对象,工厂类可以根据不同的条件创建不同的对象。
// 定义一个工厂类
class Factory {
  createProduct(type) {
    switch (type) {
      case "A":
        return new ProductA();
      case "B":
        return new ProductB();
      default:
        return null;
    }
  }
}

// 使用工厂类创建对象
const factory = new Factory();
const productA = factory.createProduct("A");
const productB = factory.createProduct("B");

console.log(productA); // ProductA {}
console.log(productB); // ProductB {}

5. 策略模式

策略模式是一种设计模式,它允许我们根据不同的条件选择不同的算法或策略来解决问题。

策略模式经常用于以下场景:

  • 算法选择 :策略模式可以帮助我们根据不同的条件选择不同的算法来解决问题。
  • 解耦 :策略模式可以将算法的选择和使用解耦,从而提高代码的可维护性。

以下是常见实现策略模式的方法:

  • 简单策略模式 :简单策略模式是一个最简单的策略模式,它通过一个策略接口来定义不同的算法,并通过一个策略工厂来创建不同的策略对象。
// 定义一个策略接口
interface Strategy {
  execute(input