工厂模式
定义
主要用于封装对象的创建过程,把逻辑性的代码封装起来,以后用到就直接调用这个函数,便于管理。调用者可以不用关心创建的代码逻辑。
常见应用场景
- 创建组件、插件
- 封装函数
单例模式
全局作用域下创建一次实例对象,在后面需要调用的地方就可以共享这个实例对象,避免多次创建。
常见应用场景
弹窗管理
弹窗通常是通过调用某个函数或方法来创建的。如果没有一个统一的管理机制,每次调用这个函数或方法都会生成一个新的弹窗实例。这样一来,如果用户连续触发多次弹窗操作,或者应用的多个部分同时需要显示弹窗,就会导致多个弹窗同时出现.
为了解决这个问题,我们通常会采用单例模式来管理弹窗。通过单例模式,我们可以确保无论多少次调用弹窗创建函数或方法,都只会返回一个唯一的弹窗实例。这样一来,无论用户如何操作,或者应用的哪个部分需要显示弹窗,都只会显示一个弹窗,避免了多个弹窗的冲突和混乱。
举例
不使用弹窗管理类的情况:
// 假设这是创建弹窗的函数
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、对工厂模式/单例模式/策略模式/代理模式的理解,常见的应用场景
本文详细解释了工厂模式用于封装对象创建过程,以及单例模式在弹窗管理中的应用。还介绍了策略模式、观察者模式和代理模式的概念及其常见应用场景。最后,通过实例展示了设计模式在面试中的重要性。
653

被折叠的 条评论
为什么被折叠?



