前端框架中的设计模式|青训营

87 阅读5分钟

前端设计模式

一、 单例模式

单例模式是一种保证一个类只有一个实例的设计模式。在前端开发中,单例模式可以用于全局状态管理、配置管理等方面。(保证类的实例只有一个)

优点与弊端

优点: 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例。由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能,避免对共享资源的多重占用。

弊端: 由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 单例类的职责过重,在一定程度上违背了单一职责原则。 不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。

单例模式的实现:


var Singleton = (function () {
  var instance;

  function createInstance() {
    // 这里是单例的实现代码
    return {};
  }

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

// 使用
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();

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

二、策略模式

定义一系列的算法,把它们一个个封装起来,并且使它们之间可以相互替换,将不变的部分和变化的部分分隔开是每个设计模式的主题,策略模式的目的就是将使用的算法和算法的实现分离开来。

优点与弊端

优点 :

  • 开闭原则 :策略模式提供了对开闭原则的支持,可以在不修改原有系统的基础上,选择不同的行为,也可以 额外扩展其它行为。
  • 避免代码冗余 :可以避免使用多重条件判定语句。可以避免出现大量的 if … else … 语句,switch语句等。
  • 安全保密 :策略模式可以提高算法的保密性和安全性。

缺点 :

  • 策略类选择 :客户端必须知道所有的策略类,并且自行决定使用哪个策略类。
  • 增加复杂性 :如果系统很复杂,会产生很多策略类。

策略模式的实现:

// 策略对象
var strategies = {
  "A": function () {
    console.log("Strategy A");
  },
  "B": function () {
    console.log("Strategy B");
  },
};

// 环境对象
function Context(strategy) {
  this.strategy = strategy;
}
Context.prototype = {
  execute: function () {
    this.strategy();
  },
};

// 使用
var contextA = new Context(strategies["A"]);
var contextB = new Context(strategies["B"]);

contextA.execute(); // 输出 "Strategy A"
contextB.execute(); // 输出 "Strategy B"

三、 代理模式

是一种通过一个代理对象控制对目标对象的访问的模式。在前端开发中,常用于实现图片懒加载、数据缓存等。代理模式可以保护目标对象,控制其访问和使用,提高代码的安全性和可读性。

优点与弊端

优点 :

分离目标对象 :代理模式能将代理对象与真实被调用的目标对象分离。 降低耦合 :在一定程度上,降低了系统耦合性,扩展性好。 保护目标对象 :代理类代理目标对象的业务逻辑,客户端直接与代理类进行交互,客户端与实际的目标对象之间没有关联。 增强目标对象 :代理类可以在目标对象基础上,添加新的功能。

缺点 :

类个数增加 :代理模式会造成系统中类的个数增加,比不使用代理模式增加了代理类,系统的复杂度增加。(所有的设计模式都有这个缺点) 性能降低 :在客户端和目标对象之间,增加了一个代理对象,造成请求处理速度变慢。

代理模式的代码实现:

const target = {
  method() {
    console.log("Target method.");
  }
};
const proxy = new Proxy(target, {
  get(target, prop) {
    console.log(`Called ${prop} method.`);
    return target[prop];
  }
});

// 使用示例
proxy.method(); // "Called method. Target method."

以上代码中,target 对象实现了原始功能,proxy 对象实现了代理功能,通过 new Proxy() 创建代理对象。代理对象通过 get 方法拦截对目标对象方法的访问,并在控制台输出信息。通过代理模式可以控制对目标对象的访问和使用,实现数据缓存、权限控制等功能,提高代码的可读性和可维护性。

四、适配器模式

是一种将一个类的接口转换成客户希望的另一个接口的设计模式。在前端开发中,适配器模式可以用于不同框架或库之间的兼容性问题。

优点与弊端

优点:

  • 可以让原本不兼容的接口协同工作,提高代码的复用性和灵活性。
  • 可以将适配器类和目标类解耦,使得适配器类和目标类可以独立变化。
  • 可以增加代码的可读性和可维护性,使代码更加清晰。

缺点:

  • 可能会增加代码的复杂度和维护成本。
  • 适配器模式需要增加一个额外的适配器类,增加了代码的量。
  • 如果设计不当,可能会导致适配器类的滥用,增加代码的混乱程度。

适配器模式的实现:

// 目标对象的接口
var Target = {
  request: function () {},
};

// 适配器对象
var Adaptor = {
  request: function () {
    // 这里是适配器的实现代码
  },
};

// 使用
var target = Target;
target.request();

var targetAdaptor = Adaptor;
targetAdaptor.request();