前端设计模式
一、 单例模式
单例模式是一种保证一个类只有一个实例的设计模式。在前端开发中,单例模式可以用于全局状态管理、配置管理等方面。(保证类的实例只有一个)
优点与弊端
优点: 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就 防止其它对象对自己的实例化,确保所有的对象都访问一个实例。由于在系统内存中只存在一个对象,因此可以 节约系统资源,当 需要频繁创建和销毁的对象时单例模式无疑可以提高系统的性能,避免对共享资源的多重占用。
弊端: 由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。 单例类的职责过重,在一定程度上违背了单一职责原则。 不适用于变化的对象,如果同一类型的对象总是要在不同的用例场景发生变化,单例就会引起数据的错误,不能保存彼此的状态。
单例模式的实现:
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();