您的位置:首页 > 房产 > 家装 > 【02问:前端常见的设计模式】

【02问:前端常见的设计模式】

2024/12/23 11:36:06 来源:https://blog.csdn.net/m0_73884922/article/details/140000309  浏览:    关键词:【02问:前端常见的设计模式】

一、策略模式

 简单来说就是一个问题匹配多个解决方案,不一定使用哪个,而且后续可能会继续增加或减少方案。主要

目录

一、策略模式

二、单例模式

方法一:使用对象字面量

方法二:使用闭包

三、观察者模式

方法一:使用 ES6 类

方法二:使用函数和闭包

方法三:使用事件机制

四、工厂模式


解决在多种相似算法存在时,使用条件语句(如if...else)导致的复杂性和难以维护的问题。

例如,购物车满减:

  • 满100减10
  • 满200减20
  • 8折
  • ......

使用策略模式实现:

<script>// 以闭包的形式把折扣方案保存const calcPrice = (function () {const sale = {'100_10': function (price) { return price -= 10 },'200_20': function (price) { return price -= 20 },'80%': function (price) { return price *= 0.8 },}// 计算折扣function calcPrice(price, type) {if(!sale[type]) return '没有这个折扣'return sale[type](price)}// 添加折扣calcPrice.add = function (type, fn) {if (sale[type]) return '折扣已经存在';sale[type] = fn}return calcPrice})()const res = calcPrice(200, '80%');console.log(res)</script>

二、单例模式

使用闭包是实现单例模式的一种常见方法。通过将类的实例保存在闭包中,并提供一个公共方法来获取该实例,可以确保只有一个实例被创建和访问。

方法一:使用对象字面量

这种方法简单直接,通过对象字面量创建一个单例对象。

const singleton = {property: 'value',method: function() {console.log('method called');}
};// 使用
singleton.method(); // 输出: method called

方法二:使用闭包

闭包是一种强大的工具,可以用来创建私有变量和方法。

const Singleton = (function() {let instance;function createInstance() {const object = new Object('I am the instance');return object;}return {getInstance: function() {if (!instance) {instance = createInstance();}return instance;}};
})();// 使用
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();console.log(instance1 === instance2); // 输出: true

三、观察者模式

观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象。当主题对象发生变化时,它会通知所有观察者对象,使它们能够自动更新自己。

在前端开发中,观察者模式非常适用于事件处理、数据绑定等场景。以下是实现观察者模式的几种常见方法:

方法一:使用 ES6 类

使用 ES6 的类语法,可以优雅地实现观察者模式。

class Subject {constructor() {this.observers = [];}addObserver(observer) {this.observers.push(observer);}removeObserver(observer) {this.observers = this.observers.filter(obs => obs !== observer);}notifyObservers(data) {this.observers.forEach(observer => observer.update(data));}
}class Observer {update(data) {console.log('Observer received data:', data);}
}// 使用
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();subject.addObserver(observer1);
subject.addObserver(observer2);subject.notifyObservers('some data'); // 所有观察者都会收到更新

方法二:使用函数和闭包

如果不使用类,也可以通过函数和闭包来实现观察者模式。

function createSubject() {let observers = [];function addObserver(observer) {observers.push(observer);}function removeObserver(observer) {observers = observers.filter(obs => obs !== observer);}function notifyObservers(data) {observers.forEach(observer => observer.update(data));}return {addObserver,removeObserver,notifyObservers};
}function createObserver() {return {update(data) {console.log('Observer received data:', data);}};
}// 使用
const subject = createSubject();
const observer1 = createObserver();
const observer2 = createObserver();subject.addObserver(observer1);
subject.addObserver(observer2);subject.notifyObservers('some data'); // 所有观察者都会收到更新

方法三:使用事件机制

前端的事件机制本身就很适合实现观察者模式,例如可以使用自定义事件。

class EventEmitter {constructor() {this.events = {};}on(event, listener) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(listener);}off(event, listener) {if (!this.events[event]) return;this.events[event] = this.events[event].filter(l => l !== listener);}emit(event, data) {if (!this.events[event]) return;this.events[event].forEach(listener => listener(data));}
}// 使用
const emitter = new EventEmitter();function listener1(data) {console.log('Listener 1 received:', data);
}function listener2(data) {console.log('Listener 2 received:', data);
}emitter.on('event', listener1);
emitter.on('event', listener2);emitter.emit('event', 'some data'); // 所有监听器都会收到更新emitter.off('event', listener1);
emitter.emit('event', 'some other data'); // 只有Listener 2 会收到更新

四、工厂模式

工厂模式(Factory Pattern)提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离,而无需指定要创建的具体类。

通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

class VehicleFactory {static createVehicle(type, model) {switch(type) {case 'car':return new Car(model);case 'truck':return new Truck(model);default:throw new Error('Unknown vehicle type');}}
}class Car {constructor(model) {this.model = model;}drive() {console.log(`${this.model} car is driving`);}
}class Truck {constructor(model) {this.model = model;}drive() {console.log(`${this.model} truck is driving`);}
}// 使用
const myCar = VehicleFactory.createVehicle('car', 'Toyota');
const myTruck = VehicleFactory.createVehicle('truck', 'Ford');myCar.drive(); // 输出: Toyota car is driving
myTruck.drive(); // 输出: Ford truck is driving

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com