JS常用設計模式匯總

1、基于類的單例模式

// PageManager.js
class PageManager {constructor(config) {if (!PageManager.instance) {this.config = config;this.initialized = false;PageManager.instance = this;this.init();}return PageManager.instance;}init() {if (this.initialized) return;console.log('Initializing with config:', this.config);// 實際初始化邏輯this.initialized = true;}generatePage(instruction) {if (!this.initialized) {throw new Error('PageManager not initialized');}const page = {...this.config,...instruction,id: Date.now()};console.log('Generated page:', page);return page;}// 更新配置(新增方法)updateConfig(newConfig) {Object.assign(this.config, newConfig);}// 獲取實例的靜態方法(推薦方式)static getInstance(config) {if (!PageManager.instance) {PageManager.instance = new PageManager(config);}return PageManager.instance;}
}// 不立即初始化,而是導出類
export default PageManager;

使用方式

// 使用方可以決定何時初始化
import PageManager from './PageManager';// 第一次獲取實例時初始化(推薦方式)
const pageManager = PageManager.getInstance({defaultTemplate: 'advanced',baseStyles: true
});// 生成頁面
const homePage = pageManager.generatePage({ title: 'Home', content: 'Welcome' 
});// 后續獲取仍然是同一個實例
const sameManager = PageManager.getInstance();
console.log(pageManager === sameManager); // true// 可以更新配置
pageManager.updateConfig({defaultTemplate: 'custom'
});

2、更優雅的變體:模塊模式單例

如果你更喜歡模塊模式而不是類,這里有一個更符合JavaScript習慣的實現:

// pageManager.js
let instance = null;
let config = {};
let initialized = false;const init = (initialConfig) => {if (initialized) {console.warn('PageManager already initialized');return;}config = {defaultTemplate: 'standard',...initialConfig};initialized = true;console.log('PageManager initialized with config:', config);
};const generatePage = (instruction) => {if (!initialized) throw new Error('PageManager not initialized');return {...config,...instruction,id: `page-${Date.now()}`};
};const updateConfig = (newConfig) => {Object.assign(config, newConfig);
};// 導出單例對象
export default {init,generatePage,updateConfig
};

使用方式:

import pageManager from './pageManager';// 在使用前初始化
pageManager.init({defaultTemplate: 'custom'
});// 使用單例
const page = pageManager.generatePage({ title: 'About' });

3、使用工廠函數(更靈活)

// 使用示例
// createPageGenerator.js
export const createPageGenerator = (initialConfig) => {const config = {defaultTemplate: 'standard',basePath: '/',...initialConfig};const generate = (instruction) => {const pageId = `${config.basePath}${instruction.slug || `page-${Date.now()}`}`;return {...config,...instruction,id: pageId,fullPath: `${config.basePath}${instruction.path || ''}`,createdAt: new Date()};};const updateConfig = (newConfig) => {Object.assign(config, newConfig);};return {generate,updateConfig,getConfig: () => ({ ...config })};
};// 使用示例
// 可以創建多個實例或單個實例使用

基本使用

// 使用示例
import { createPageGenerator } from './createPageGenerator';// 1. 創建實例(簡單配置)
const simpleGenerator = createPageGenerator();
const page1 = simpleGenerator.generate({ title: 'Home' });
console.log(page1);

4、發布-訂閱模式 (Pub-Sub Pattern)

用途:觀察者模式的變體,使用主題/通道概念解耦發布者和訂閱者。

class EventBus {constructor() {this.events = {};}subscribe(eventName, callback) {if (!this.events[eventName]) {this.events[eventName] = [];}this.events[eventName].push(callback);}publish(eventName, data) {if (this.events[eventName]) {this.events[eventName].forEach(callback => callback(data));}}unsubscribe(eventName, callback) {if (this.events[eventName]) {this.events[eventName] = this.events[eventName].filter(cb => cb !== callback);}}
}// 使用
const bus = new EventBus();// 訂閱
const logData = data => console.log('Received:', data);
bus.subscribe('dataUpdate', logData);// 發布
bus.publish('dataUpdate', { newData: 123 });// 取消訂閱
bus.unsubscribe('dataUpdate', logData);// 實際應用:Vue的EventBus、組件間通信

5、觀察者模式 (Observer Pattern)

// 主題(被觀察者)
class Subject {constructor() {this.observers = [];}subscribe(observer) {this.observers.push(observer);}unsubscribe(observer) {this.observers = this.observers.filter(obs => obs !== observer);}notify(data) {this.observers.forEach(observer => observer.update(data));}
}// 觀察者
class Observer {update(data) {console.log('Observer received:', data);}
}// 使用
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();subject.subscribe(observer1);
subject.subscribe(observer2);subject.notify('Hello observers!'); // 兩個觀察者都會收到通知// 實際應用:事件系統、狀態管理(如Redux)、數據綁定

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/84668.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/84668.shtml
英文地址,請注明出處:http://en.pswp.cn/web/84668.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

邁向軟件開發 T 型人才之路:構建多元能力體系

在軟件開發的廣袤天地里,T 型人才備受矚目。這類人才猶如具備強大能量的 “多面手”,既有深入專精的技術能力,又有廣泛多元的知識與技能儲備,能夠從容應對復雜多變的項目需求,引領行業創新發展。于當今社會而言&#x…

SALMONN-omni論文閱讀

論文鏈接 項目鏈接 名詞理解: backchanneling: 指的是聽話人在不打斷說話人的情況下,用簡短的語氣詞或動作表示“我在聽”“我理解了”的反饋。 常見示例包括: “嗯哼”(“uh-huh”) “對的”&#xff08…

區塊鏈:什么是DeFi?

DeFi(去中心化金融,Decentralized Finance) 是一種基于區塊鏈技術的金融生態系統,旨在通過去中心化的方式提供傳統金融服務(如借貸、交易、儲蓄等),無需依賴銀行、經紀商等中介機構。DeFi主要構…

idea編譯器使用git拉取、提交非常慢的原因和解決方案

前言 最近在公司換了一個電腦,但是發現這個電腦用idea編譯器使用git拉取、提交各種操作非常慢,有時候需要等10分鐘左右,這明顯是不對勁的,說明電腦的某些環境影響到git和idea之間的整合了。 目錄 在idea拉取代碼非常慢的原因 解決方案 在idea拉取代碼非常慢的原因 經過排查…

C語言變量的奇妙世界:探秘作用域

資料合集下載鏈接: ??https://pan.quark.cn/s/472bbdfcd014?? 在C語言的編程世界里,變量是我們存儲和操作數據的基礎。然而,僅僅知道如何定義和使用變量是遠遠不夠的。一個更深層次的理解,在于掌握變量的“作用域”——也就是變量在程序中可以被訪問和使用的范圍。這就…

恒流源和直流穩壓電源 電路

目錄 前言一、恒流源電路1.低端反饋2.低端反饋注意事項注意1:電阻Rx注意2:三極管和運放的限制 3.高端反饋注意:自激振蕩方案二 二、直流穩壓電源電流1.帶反饋2.不帶反饋3.區別 前言 基礎知識可以看個人筆記:個人筆記 一、恒流源…

那些年,曾經輝煌過的數據庫

滾滾長江東逝水,浪花淘盡英雄! 數據庫的演進史,正是這樣一部“英雄迭代”的壯闊史詩。從早期數據模型的拓荒者,到關系型數據庫的商業巨頭;從桌面應用的普及者,再到開源與大數據時代的弄潮兒;每…

2D曲線點云平滑去噪

2D曲線點云,含許多噪聲,采用類似移動最小二乘的方法(MLS)分段擬合拋物線并投影至拋物線,進行點云平滑去噪。 更通俗的說法是讓有一定寬度的曲線點云,變成一條細曲線上的點。 分兩種情況進行討論: 1&#…

【平面波導外腔激光器專題系列】用于精密測量的平面波導外腔激光器特性

----翻譯自Kenji Numata等人的文章 摘要 1542 nm平面波導外腔激光器PW-ECL具有足夠低的噪聲非常適合精密測量應用。與 0.1mHz至100kHz 之間,其頻率和強度噪聲與非平面環形振蕩器 NPRO和光纖激光器相當或更好。通過將 PW-ECL 的頻率穩定在乙炔(13C2H2&a…

文件時間修改器

文件時間修改器是一款幫助用戶修改文件創建時間的軟件,支持毫秒級時間的修改,包括文件的創建時間、修改時間、訪問時間等時間都支持修改,可以批量處理文件。 飛貓云下載 | 備用下載1 |備用下載2 基本簡介 本軟件主要為批量修改文件的創建時…

倉頡語言實戰:MQTT物聯網開發

目錄 引言 mqtt4cj庫的使用 申請倉頡編程語言內測 下載STDX 測試程序 結束語 引言 最近一直在學習倉頡語言,由于我對物聯網比較感興趣,自然想到寫一個MQTT的程序,好在找到了mqtt4cj庫,今天分享一下學習心得。 mqtt4cj庫的…

OpenCV CUDA模塊設備層-----用于在 CUDA 核函數中訪問紋理數據的一個封裝類TexturePtr()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 TexturePtr<T, R> 是 OpenCV 的 opencv_cudev 模塊中用于在 CUDA 核函數中訪問紋理數據的一個封裝類。它主要用于將一個已創建好的 cudaTe…

Spring Boot的自動裝配和自動配置

Spring Boot的自動裝配&#xff08;Auto Wiring&#xff09;和自動配置&#xff08;Auto Configuration&#xff09;是兩個不同的概念&#xff0c;它們在Spring框架中各自有不同的作用和用途。下面我將詳細解釋它們的區別和聯系。 自動裝配&#xff08;Auto Wiring&#xff09…

如何用 vue-office 快速搭建文檔在線預覽服務

1. 什么是 vue-office 1.1 vue-office 簡介 vue-office 是一個基于 Vue 的組件庫,用于在 Web 應用中快速集成 Office 文檔的在線預覽功能。它支持 Word、Excel 和 PowerPoint 等多種格式,并提供了簡潔的 API 接口和豐富的自定義選項。 1.2 支持的文檔類型與核心特性 支持的…

Python爬蟲(六):Scrapy框架

"Scrapy到底該怎么學&#xff1f;"今天&#xff0c;我將用這篇萬字長文&#xff0c;帶你從零開始掌握Scrapy框架的核心用法&#xff0c;并分享我在實際項目中的實戰經驗&#xff01;建議收藏?&#xff01; 一、Scrapy簡介&#xff1a;為什么選擇它&#xff1f; 1.…

Linux中關閉swap分區

在 Linux 系統中關閉 swap 分區&#xff08;或交換文件&#xff09;的步驟如下&#xff0c;請務必在操作前保存所有數據&#xff0c;以免丟失&#xff1a; &#x1f4cc; 完整操作步驟&#xff1a; 1. 查看當前 swap 使用情況 free -h swapon --show # 查看活躍的 swap 設…

RPGMZ游戲引擎之如何設計每小時開啟一次的副本

本文知識點 1. 獲取時間 2. 時間格式要正確 3. 事件內如何設計 正文開始 1. 獲取時間 首先獲取當前時間 然后保存在 事件內的變量里面 后需要判斷時間是否相等 function 獲取當前日期(){const now new Date();return now.toISOString();}; 2. 時間格式要正確 now.toI…

學習路之uniapp--uniapp擴展uni-ui

這里寫目錄標題 一、新建項目二、下載導入插件三、直接創建uni-ui項目 一、新建項目 二、下載導入插件 三、直接創建uni-ui項目 創建uniapp項目時&#xff0c;直接創建uni-ui項目

Kotlin 2.6 猜數小游戲

本次實戰通過開發猜數小游戲&#xff0c;深入學習了 Kotlin 編程的循環控制和條件判斷。游戲要求計算機隨機生成一個數字&#xff0c;用戶通過輸入猜測&#xff0c;程序根據猜測結果給出提示&#xff0c;直到猜中為止。通過實現這一過程&#xff0c;我們掌握了如何使用 while 循…

RNN工作原理和架構

## 1. 什么是 RNN&#xff1f; * **全稱&#xff1a;** Recurrent Neural Network&#xff08;循環神經網絡&#xff09; * **核心特點&#xff1a;** 它是一種專門設計用來處理**序列數據**的神經網絡。 * **核心能力&#xff1a;** 擁有“記憶”能力&#xff0c;能夠利用**…