今天要介紹的是 Factory 模式,也是 GoF 提及的模式之一。
在軟體開發時,有時需要建立物件,但建立物件的過程可能非常複雜或需要大量配置,需要在不指定具體類別的情況下,能依據所處環境來建立物件,以增加程式碼的彈性和可維護性。
如何在不指定具體類的情況下,建立多種類型的物件,且物件還能有共享的共通屬性?
使用工廠(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 作為解決方案缺點如下:
其實在 JavaScript 中,factory 模式並不算是真正的模式,它其實就只是一個不用 new
關鍵字來傳回物件的函式,但其實在多數情況下,要建立物件時用 new
來建立新實例會比用 factory 函式直接回傳物件更省效能,因為用 new
來建構實例,物件還可以共用方法,但用函式來回傳新物件的話,每次都會建立物件各自的方法,反而會消耗更多記憶體空間。