一、策略模式
简单来说就是一个问题匹配多个解决方案,不一定使用哪个,而且后续可能会继续增加或减少方案。主要
目录
[方法一:使用 ES6 类](#方法一:使用 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