iT邦幫忙

2024 iThome 鐵人賽

DAY 7
0

https://ithelp.ithome.com.tw/upload/images/20240921/201682019Q8BSw6Lng.png

今天要介紹的是 Factory 模式,也是 GoF 提及的模式之一。

情境

在軟體開發時,有時需要建立物件,但建立物件的過程可能非常複雜或需要大量配置,需要在不指定具體類別的情況下,能依據所處環境來建立物件,以增加程式碼的彈性和可維護性。

問題

如何在不指定具體類的情況下,建立多種類型的物件,且物件還能有共享的共通屬性?

權衡

  • 建立物件的彈性:在運行時(runtime)要能根據條件選擇具體物件類型,可輕鬆擴展或切換不同實現,但也可能提升管理時的複雜度,另外,運行時才決定具體實現可能會比靜態時決策更慢,而可能增加處理時間而影響效能
  • 解耦物件創建和使用:使用者不需知道物件的具體類型和創建細節,只需知道如何取得物件,可降低依賴性並提升靈活度,但也可能導致多層次的封裝而提升的應用的複雜度
  • 封裝建立過程:將建立物件的過程集中管理,如建構、配置和初始化等步驟,封裝可降低系統各部分間的依賴關係,但過度封裝也可能提升系統複雜度

解決方案

使用工廠(Factory)來封裝建立物件的過程,不使用建構子來建立物件,而是提供用於建立物件的通用介面,讓人在其中指明要建立的物件類型,一句話來說,就是用 factory 函式來建立物件,不須透過 class 或 constructors 建立。
所謂 factory 函式就是會回傳物件的函式,我們可透過函式的參數預設值來設定物件的預設屬性值,舉例來說,我們可建立一個 createBook 的函式,用來建立書籍物件:

const createBook = ({ title = 'dafault title', author = 'default author', cover = 'https://via.placeholder.com/150' }) => ({
  title,
  author,
  cover,
  setTitle(newTitle) {
    this.title = newTitle;
    return this;
  },
});

接著我們可呼叫這函式並傳入我們希望的物件屬性值,就可得到建立好的物件:

const jsBook = createBook({
  title: 'JavaScript',
  author: 'Foo',
  cover: 'https://example.com/covers/JavaScript.png',
});

const reactBook = createBook({
  title: 'React',
  author: 'Bar',
  cover: 'https://example.com/covers/React.png',
});

console.log(jsBook);
console.log(reactBook);

優點

以 Factory 作為解決方案缺點如下:

  • 可達到 DRY(Don't Repeat Yourself)的原則:當我們需建立多個共享相同屬性物件時,工廠模式可讓我們避免重複相同程式碼,factory 函式能依據當前環境或使用者特定的配置參數來回傳自訂物件
  • 降低程式碼間的耦合度、提高彈性:將物件的建立和使用分離,只透過工廠提供的介面操作,可降低程式碼之間的依賴關係,也提升運用的彈性

缺點

其實在 JavaScript 中,factory 模式並不算是真正的模式,它其實就只是一個不用 new 關鍵字來傳回物件的函式,但其實在多數情況下,要建立物件時用 new 來建立新實例會比用 factory 函式直接回傳物件更省效能,因為用 new 來建構實例,物件還可以共用方法,但用函式來回傳新物件的話,每次都會建立物件各自的方法,反而會消耗更多記憶體空間。

Reference


上一篇
[Day 06] Prototype 模式
下一篇
[Day 08] Facade 模式
系列文
30天的 JavaScript 設計模式之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言