靜態工廠模式 (Static Factory Pattern) 的應用與優勢

引言 在軟體開發中,物件的建立是最常見的操作之一。我們通常直接使用 new 關鍵字來實例化物件,但當建立過程變得複雜、需要非同步操作,或者我們想對建立過程有更多控制時,直接使用 new 可能就不夠了。 本文將介紹靜態工廠模式如何解決這些問題,並以 ImageLoader 重構為例,展示實際應用場景 什麼是工廠模式? 工廠模式的核心概念是將物件的建立邏輯從直接的 new 呼叫中抽離出來,委託給一個專門的「工廠」來負責。這樣做的主要目的是降低耦合、提高彈性。 工廠模式有多種變體: 簡單工廠:一個工廠類別負責建立多種產品 - 👉 More 工廠方法:每個產品都有自己的工廠 - 👉 More 抽象工廠:建立相關產品族 - 👉 More 靜態工廠方法:本文重點討論的模式 靜態工廠方法詳解 靜態工廠方法是類別內部的一個 static 方法,負責建立並返回該類別的實例(或其子類別的實例)。 命名慣例 常見的靜態工廠方法名稱: create() - 建立新實例 最常見的命名,表示建立一個全新的實例: // 組件建立 const button = Button.create({ text: 'Click me', onClick: handleClick }); // API 客戶端建立 const apiClient = ApiClient.create({ baseURL: 'https://api.example.com' }); // 資料庫連接建立 const dbConnection = await DatabaseConnection.create(config); of() - 從參數建立實例 表示從某些參數或值建立實例:...

July 10, 2025 · 4 分鐘 · Rhan0

開發慣例: Coding style

Singleton 的寫法 class AnimalManager { constructor() { this.init() } init() { this.name = 'AnimalManager' } } export default new AnimalManager() class AnimalManager { constructor() { if (Animal.instance) { return Animal.instance } this.init() Animal.instance = this } init() { this.name = 'AnimalManager' } } export default AnimalManager // typescript 可以用靜態工廠模式 (Static Factory Pattern) class AnimalManager { private static instance: AnimalManager; public static getInstance(): AnimalManager { if (!AnimalManager.instance) { AnimalManager.instance = new AnimalManager(); } return AnimalManager....

January 27, 2025 · 1 分鐘 · Rhan0

開發慣例: JavaScript 命名慣例

變數的命名 (for Variables) 使用 camelCase 為變數命名 // bad var dogname = 'Droopy'; // bad var dog_name = 'Droopy'; // bad var DOGNAME = 'Droopy'; // bad var DOG_NAME = 'Droopy'; // good var dogName = 'Droopy'; 明確表明意義的命名 (self-explanatory and describe the stored value) // bad var d = 'Scooby-Doo'; // bad var name = 'Scooby-Doo'; // good var dogName = 'Scooby-Doo'; 布林值的命名 (for Booleans) 使用開頭為 is/has 的命名 (Use is or has as prefixes)...

January 27, 2025 · 2 分鐘 · Rhan0

開發慣例: 通用命名慣例

淺而易懂的命名 (Use Intention-Revealing Names) 如果一個命名,還需要註解來解釋它,就代表還不夠清楚 // Bad var dog; // the dog is barking // Good var barkingDog; 有意義的命名 (Make Meaningful Distinctions) 使用帶有目的性或是意義明確的命名,避免使用縮寫、或是用數字編號作為命名 // Bad var e = 'event' // Good var event = 'event' 避免誤導 (Avoid Disinformation) 避免用不同字眼代表同一件事,例如:info/data 避免贅字 避免兩個命名太相像 可以被搜尋 (Use Searchable Names) 避免用數字與單一字母命名,可改採用 Constant 或 Enum 賦予意義 longer names比shorter names好,至少搜尋容易定位 可以被發音 (Use Pronounceable Names) 使用可以發音的命名可以幫助溝通

January 27, 2025 · 1 分鐘 · Rhan0

WebRTC 101

WebRTC (Web Real-Time Communication) 是一個支援網頁瀏覽器進行即時語音對話或影像的API,有許多廣泛用途,例如 Zoom, google meet… 這類型視訊會議的實作,由兩項核心技術構成: 1. Media Capture and Streams API 就是 MediaStreams API,可以藉由這個 API 擷取本地端的多媒體串流(e.g video, audio),顯示在瀏覽器上或是進行更多處理/傳送。 2. Peer-To-Peer Connection(P2P) 點對點連線,意指用戶端(client)電腦之間能夠互相交換資料,無需透過主機端(server)來處理各用戶端的資料傳輸。 一般來說,我們最熟悉的網路溝通模式(HTTP超文本傳輸協定)如下圖: P2P的溝通方式為,各自先連線到 server 確認彼此連線後,client A 跟 client B 就能彼此傳輸資料,如下圖: WebRTC 三種架構 P2P, SFU, MCU 圖片擷取自: liveswitch P2P 多個終端之間兩兩進行連接,形成一個網狀結構,每一端直接向另一端發送媒體或從另一端接收媒體,隨著參與方數量的增加,會難以管理 MCU 從各端點接收媒體,然後將其混合後一起廣播給所有其他端點 SFU 和 MCU不同的地方在於不會把媒體訊號混流,收到某個終端共享的音視頻流後,就直接將該音視頻流轉發給房間內的其他終端,通常用於有兩個以上的連線(e.g 多人會議) WebRTC 幾個核心的 API getUserMedia( ) 擷取 user 的 audio, video,使用時需傳入 {audio: boolean, video: boolean} const constraints = { audio: true }; navigator....

October 20, 2023 · 2 分鐘 · Rhan0

Nuxt i18n 優化

intro Nuxt i18n install $ npm install nuxt-i18n Example // nuxt.config.js { modules: [ 'nuxt-i18n' ], i18n: { locales: ['en', 'zh'], defaultLocale: 'en', vueI18n: { fallbackLocale: 'en', messages: { en: { welcome: 'Welcome' }, zh: { welcome: '歡迎' } } } } } <template> <main> <h1>{{ $t('greeting') }}</h1> <nuxt-link v-if="$i18n.locale !== 'en'" :to="switchLocalePath('en')" > English </nuxt-link> <nuxt-link v-if="$i18n.locale !== 'zh_TW'" :to="switchLocalePath('zh_TW')" > 繁體中文 </nuxt-link> </main> </template> Set Locale // plugins/i18n.ts import { Context } from '@nuxt/types' import VueI18n from 'vue-i18n' let vueI18n: VueI18n | null = null export default function({ app, route }: Context): Promise<void> { vueI18n = app....

August 31, 2020 · 3 分鐘 · Rhan0

工廠方法模式 (Factory Method Pattern)

什麼是工廠方法模式? 工廠方法模式定義了一個建立物件的介面,但讓子類別決定要實例化哪個類別。這種模式將物件的建立延遲到子類別,符合開放封閉原則。 核心概念 抽象工廠介面:定義建立物件的抽象方法 具體工廠類別:每個產品都有自己的工廠 開放封閉原則:新增產品時不需要修改現有程式碼 實際範例 // 產品介面 interface Vehicle { drive(): void; } // 具體產品 class Car implements Vehicle { drive(): void { console.log('Driving a car'); } } class Bike implements Vehicle { drive(): void { console.log('Riding a bike'); } } // 抽象工廠介面 interface VehicleFactory { create(): Vehicle; } // 具體工廠類別 class CarFactory implements VehicleFactory { create(): Vehicle { return new Car(); } } class BikeFactory implements VehicleFactory { create(): Vehicle { return new Bike(); } } // 使用方式 const carFactory = new CarFactory(); const bikeFactory = new BikeFactory(); const car = carFactory....

July 10, 2025 · 1 分鐘 · Rhan0

抽象工廠模式 (Abstract Factory Pattern)

什麼是抽象工廠模式? 抽象工廠模式提供一個建立一系列相關或相互依賴物件的介面,而不需要指定它們的具體類別。這種模式確保產品族內的一致性,常用於 UI 框架的實作。 核心概念 產品族:一系列相關的產品 抽象工廠介面:定義建立產品族的方法 具體工廠:實作特定產品族的建立邏輯 產品一致性:確保同一產品族內的產品能正常配合 實際範例 // 產品介面 interface Button { render(): void; } interface Input { render(): void; } // Material UI 產品族 class MaterialButton implements Button { render(): void { console.log('Rendering Material UI button'); } } class MaterialInput implements Input { render(): void { console.log('Rendering Material UI input'); } } // Bootstrap 產品族 class BootstrapButton implements Button { render(): void { console.log('Rendering Bootstrap button'); } } class BootstrapInput implements Input { render(): void { console....

July 10, 2025 · 1 分鐘 · Rhan0

簡單工廠模式 (Simple Factory Pattern)

什麼是簡單工廠模式? 簡單工廠模式是最基本的工廠模式,它提供一個統一的介面來建立物件,而不需要直接使用 new 關鍵字。這種模式將物件的建立邏輯集中管理,提高了程式碼的可維護性。 核心概念 統一介面:提供一個靜態方法來建立物件 集中管理:將建立邏輯集中在一個地方 降低耦合:客戶端不需要知道具體的實作細節 實際範例 // 產品介面 interface Vehicle { drive(): void; } // 具體產品 class Car implements Vehicle { drive(): void { console.log('Driving a car'); } } class Bike implements Vehicle { drive(): void { console.log('Riding a bike'); } } // 簡單工廠 class VehicleFactory { static create(type: 'car' | 'bike'): Vehicle { switch (type) { case 'car': return new Car(); case 'bike': return new Bike(); default: throw new Error('Unknown vehicle type'); } } } // 使用方式 const car = VehicleFactory....

July 10, 2025 · 1 分鐘 · Rhan0

如何自動切換專案 NodeJS 版本

前言 前端開發人員經常需要在數個專案中切換,NodeJS 版本也會因專案不同而切換來切換去,雖然有方便的 nvm、n 等管理工具可以進行版本控管,但依舊是“手動”來執行切換指令,長期下來是一種困擾,更不用說如果同時在多個專案裡,更容易出現問題。 確保所有專案環境裡的 NodeJS 版本雖然不是什麼嚴重的大事,但可以讓我們從開發到 release 的程式碼運作能按預期的方式進行,至少比較不會發生我在開發時看到的結果和 release 出去後運行的結果不一樣的困擾。 近期團隊正好遇到這個痛點,為了讓溝通成本降低,也減少不必要的人為疏失,萌生了讓 NodeJS 版本隨著不同專案自動切換的想法,也找到了解決方式記錄在這邊。 實作 我是使用 zsh,如果要用其他方式可以參考shell config section. 第一步:新增自動切換 NodeJS 的功能 在專案中先切換成正確的 node 版本 nvm use 18.18.0 輸入以下指令產生一個 .nvmrc 檔案 node -v > .nvmrc 再來就是要去terminal設定一下,打開 $HOME/.zshrc sudo vim .zshrc 在檔案最後的地方加入以下這段,重新啟動 vscode,只要專案有 .nvmrc,你會發現它會自動幫你變更 NodeJS 版本! # place this after nvm initialization! autoload -U add-zsh-hook load-nvmrc() { local node_version="$(nvm version)" local nvmrc_path="$(nvm_find_nvmrc)" if [ -n "$nvmrc_path" ]; then local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")") if [ "$nvmrc_node_version" = "N/A" ]; then nvm install elif [ "$nvmrc_node_version" !...

September 27, 2023 · 1 分鐘 · Rhan0