前端中的设计模式(工厂模式、单例模式、代理模式、策略模式)

本文详细解释了工厂模式用于封装对象创建过程,以及单例模式在弹窗管理中的应用。还介绍了策略模式、观察者模式和代理模式的概念及其常见应用场景。最后,通过实例展示了设计模式在面试中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工厂模式

定义

主要用于封装对象的创建过程,把逻辑性的代码封装起来,以后用到就直接调用这个函数,便于管理。调用者可以不用关心创建的代码逻辑。

常见应用场景

  • 创建组件、插件
  • 封装函数

单例模式

全局作用域下创建一次实例对象,在后面需要调用的地方就可以共享这个实例对象,避免多次创建。

常见应用场景

弹窗管理

弹窗通常是通过调用某个函数或方法来创建的。如果没有一个统一的管理机制,每次调用这个函数或方法都会生成一个新的弹窗实例。这样一来,如果用户连续触发多次弹窗操作,或者应用的多个部分同时需要显示弹窗,就会导致多个弹窗同时出现.

为了解决这个问题,我们通常会采用单例模式来管理弹窗。通过单例模式,我们可以确保无论多少次调用弹窗创建函数或方法,都只会返回一个唯一的弹窗实例。这样一来,无论用户如何操作,或者应用的哪个部分需要显示弹窗,都只会显示一个弹窗,避免了多个弹窗的冲突和混乱。

举例
不使用弹窗管理类的情况:

// 假设这是创建弹窗的函数  
function createPopup() {  
    // 这里只是简单模拟弹窗的创建,实际上可能会更复杂  
    const popup = document.createElement('div');  
    popup.textContent = '这是一个弹窗';  
    popup.style.position = 'fixed';  
    popup.style.top = '50%';  
    popup.style.left = '50%';  
    popup.style.transform = 'translate(-50%, -50%)';  
    popup.style.padding = '20px';  
    popup.style.backgroundColor = 'white';  
    popup.style.border = '1px solid black';  
    document.body.appendChild(popup);  
    return popup; // 返回创建的弹窗实例  
}  
  
// 假设这是触发弹窗的某个事件处理函数  
function triggerPopup() {  
    createPopup(); // 每次调用都会创建新的弹窗实例  
}  
  
// 假设有两个按钮,点击后都会触发弹窗  
const button1 = document.getElementById('button1');  
const button2 = document.getElementById('button2');  
button1.addEventListener('click', triggerPopup);  
button2.addEventListener('click', triggerPopup);

使用单例模式管理弹窗

// 使用单例模式管理弹窗  
class PopupManager {  
    constructor() {  
        this.popup = null; // 弹窗实例存储在这里  
    }  
  
    // 创建或返回弹窗实例  
    getPopup() {  
        if (!this.popup) {  
            this.popup = this.createPopup();  
        }  
        return this.popup;  
    }  
  
    // 实际创建弹窗的逻辑  
    createPopup() {  
        const popup = document.createElement('div');  
        popup.textContent = '这是一个弹窗';  
        popup.style.position = 'fixed';  
        popup.style.top = '50%';  
        popup.style.left = '50%';  
        popup.style.transform = 'translate(-50%, -50%)';  
        popup.style.padding = '20px';  
        popup.style.backgroundColor = 'white';  
        popup.style.border = '1px solid black';  
        document.body.appendChild(popup);  
        return popup;  
    }  
  
    // 显示弹窗  
    showPopup() {  
        const popup = this.getPopup();  
        // 这里可以添加逻辑来确保弹窗可见,比如修改其样式等  
    }  
  
    // 隐藏弹窗  
    hidePopup() {  
        if (this.popup) {  
            this.popup.style.display = 'none';  
        }  
    }  
}  
  
// 创建一个PopupManager的实例(单例)  
const popupManager = new PopupManager();  
  
// 触发弹窗的某个事件处理函数现在使用PopupManager  
function triggerPopup() {  
    popupManager.showPopup(); // 无论调用多少次,都只操作同一个弹窗实例  
}  
  
// 假设有两个按钮,点击后都会触发弹窗  
const button1 = document.getElementById('button1');  
const button2 = document.getElementById('button2');  
button1.addEventListener('click', triggerPopup);  
button2.addEventListener('click', triggerPopup);

全局状态管理

配置管理

策略模式

定义

策略模式把算法和算法的实现分开,算法单独封装起来

常见的应用场景

  • 表单验证
  • 请求处理逻辑(post、get等)
  • 数据格式处理

观察者模式

定义

是一种一对多的依赖关系。
有多个观察者同时监听一个对象,当该对象发生变化时,所有的观察者都会收到通知并自动更新

常见的应用场景

  • 双向数据绑定
  • 页面事件监听
  • 表单验证

代理模式

定义

为一个对象提供一个占位符,控制其访问,像房产中介

常见应用场景

  • 资源加载,比如图片等
  • 权限验证,在操作之前进行权限验证
  • 缓存
// 假设这是我们的目标对象,它有一个执行开销较大的方法  
const target = {  
    expensiveOperation: function(key) {  
        // 模拟一个耗时操作  
        console.log('正在执行耗时操作...');  
        return `结果:${key}`;  
    }  
};  
  
// 代理对象,实现缓存功能  
const proxy = {  
    cache: {}, // 缓存对象  
    expensiveOperation: function(key) {  
        // 检查缓存中是否有结果  
        if (key in this.cache) {  
            console.log('从缓存中获取结果...');  
            return this.cache[key];  
        }  
  
        // 缓存中无结果,调用目标对象的方法  
        const result = target.expensiveOperation(key);  
  
        // 将结果存入缓存  
        this.cache[key] = result;  
  
        // 返回结果  
        return result;  
    }  
};  
  
// 使用代理对象  
console.log(proxy.expensiveOperation('key1')); // 执行操作并缓存结果  
console.log(proxy.expensiveOperation('key1')); // 从缓存中获取结果  
console.log(proxy.expensiveOperation('key2')); // 执行操作并缓存新结果



// 举例-实现求积的函数
// 定义求积的函数
let result = function() {
	console.log('计算中...')
	let r = 1
	for(let i=0; i<arguments.length;  i++){
		r = r * arguments[i]
	}
	return r
}

// 缓存代理的函数
let proxyResult = (function() {
		var cache = {}
		// 返回处理的结果
		return function() {
			// arguments也不一定是数组,所以要转化
			let arg = Array.prototype.join.call(arguments,',')
			console.log(arg)
			if(arg in cache) {
				return cache[arg]
			}
			
			// 缓存中没有
			return (cache[arg] = result.apply(this, arguments))
		}
	}
)()

console.log(proxyResult(1,2,3,4))
console.log(proxyResult(1,2,3,4))

------ 2024/4/1添加-------

面试题:

1、说说对设计模式的理解,常见的设计模式有哪些
2、对工厂模式/单例模式/策略模式/代理模式的理解,常见的应用场景

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值