'JavaScript設計模式之工廠模式(Factory Method Pattern)'

JavaScript 設計模式 騰訊QQ 前端在路上 2019-08-19
"
"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

JavaScript設計模式之工廠模式(Factory Method Pattern)

工廠模式的項目實戰應用

在實際的前端業務中,最常用的簡單工廠模式。如果不是超大型的項目,是很難有機會使用到工廠方法模式和抽象工廠方法模式的。下面我介紹在Vue項目中實際使用到的簡單工廠模式的應用。

在普通的vue + vue-router的項目中,我們通常將所有的路由寫入到router/index.js這個文件中。下面的代碼我相信vue的開發者會非常熟悉,總共有5個頁面的路由:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

JavaScript設計模式之工廠模式(Factory Method Pattern)

工廠模式的項目實戰應用

在實際的前端業務中,最常用的簡單工廠模式。如果不是超大型的項目,是很難有機會使用到工廠方法模式和抽象工廠方法模式的。下面我介紹在Vue項目中實際使用到的簡單工廠模式的應用。

在普通的vue + vue-router的項目中,我們通常將所有的路由寫入到router/index.js這個文件中。下面的代碼我相信vue的開發者會非常熟悉,總共有5個頁面的路由:

JavaScript設計模式之工廠模式(Factory Method Pattern)

當涉及權限管理頁面的時候,通常需要在用戶登陸根據權限開放固定的訪問頁面並進行相應權限的頁面跳轉。但是如果我們還是按照老辦法將所有的路由寫入到router/index.js這個文件中,那麼低權限的用戶如果知道高權限路由時,可以通過在瀏覽器上輸入url跳轉到高權限的頁面。所以我們必須在登陸的時候根據權限使用vue-router提供的addRoutes方法給予用戶相對應的路由權限。這個時候就可以使用簡單工廠方法來改造上面的代碼。

在router/index.js文件中,我們只提供/login這一個路由頁面。

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

JavaScript設計模式之工廠模式(Factory Method Pattern)

工廠模式的項目實戰應用

在實際的前端業務中,最常用的簡單工廠模式。如果不是超大型的項目,是很難有機會使用到工廠方法模式和抽象工廠方法模式的。下面我介紹在Vue項目中實際使用到的簡單工廠模式的應用。

在普通的vue + vue-router的項目中,我們通常將所有的路由寫入到router/index.js這個文件中。下面的代碼我相信vue的開發者會非常熟悉,總共有5個頁面的路由:

JavaScript設計模式之工廠模式(Factory Method Pattern)

當涉及權限管理頁面的時候,通常需要在用戶登陸根據權限開放固定的訪問頁面並進行相應權限的頁面跳轉。但是如果我們還是按照老辦法將所有的路由寫入到router/index.js這個文件中,那麼低權限的用戶如果知道高權限路由時,可以通過在瀏覽器上輸入url跳轉到高權限的頁面。所以我們必須在登陸的時候根據權限使用vue-router提供的addRoutes方法給予用戶相對應的路由權限。這個時候就可以使用簡單工廠方法來改造上面的代碼。

在router/index.js文件中,我們只提供/login這一個路由頁面。

JavaScript設計模式之工廠模式(Factory Method Pattern)

我們在router/文件夾下新建一個routerFactory.js文件,導出routerFactory簡單工廠函數,用於根據用戶權限提供路由權限,代碼如下

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

JavaScript設計模式之工廠模式(Factory Method Pattern)

工廠模式的項目實戰應用

在實際的前端業務中,最常用的簡單工廠模式。如果不是超大型的項目,是很難有機會使用到工廠方法模式和抽象工廠方法模式的。下面我介紹在Vue項目中實際使用到的簡單工廠模式的應用。

在普通的vue + vue-router的項目中,我們通常將所有的路由寫入到router/index.js這個文件中。下面的代碼我相信vue的開發者會非常熟悉,總共有5個頁面的路由:

JavaScript設計模式之工廠模式(Factory Method Pattern)

當涉及權限管理頁面的時候,通常需要在用戶登陸根據權限開放固定的訪問頁面並進行相應權限的頁面跳轉。但是如果我們還是按照老辦法將所有的路由寫入到router/index.js這個文件中,那麼低權限的用戶如果知道高權限路由時,可以通過在瀏覽器上輸入url跳轉到高權限的頁面。所以我們必須在登陸的時候根據權限使用vue-router提供的addRoutes方法給予用戶相對應的路由權限。這個時候就可以使用簡單工廠方法來改造上面的代碼。

在router/index.js文件中,我們只提供/login這一個路由頁面。

JavaScript設計模式之工廠模式(Factory Method Pattern)

我們在router/文件夾下新建一個routerFactory.js文件,導出routerFactory簡單工廠函數,用於根據用戶權限提供路由權限,代碼如下

JavaScript設計模式之工廠模式(Factory Method Pattern)

在登陸頁導入該方法,請求登陸接口後根據權限添加路由:

"
JavaScript設計模式之工廠模式(Factory Method Pattern)

什麼是工廠模式?

工廠模式是用來創建對象的一種最常用的設計模式。我們不暴露創建對象的具體邏輯,而是將將邏輯封裝在一個函數中,那麼這個函數就可以被視為一個工廠。工廠模式根據抽象程度的不同可以分為:簡單工廠工廠方法抽象工廠。

如果只接觸過JavaScript這門語言的的人可能會對抽象這個詞的概念有點模糊,因為JavaScript 一直將abstract作為保留字而沒有去實現它。如果不能很好的理解抽象的概念,那麼就很難理解工廠模式中的三種方法的異同。

下面我們來看一下之前提到的工廠模式的三種實現方法: 簡單工廠模式、工廠方法模式、抽象工廠模式。

簡單工廠模式

簡單工廠模式又叫靜態工廠模式,由一個工廠對象決定創建某一種產品對象類的實例。主要用來創建同一類對象。

在實際的項目中,我們常常需要根據用戶的權限來渲染不同的頁面,高級權限的用戶所擁有的頁面有些是無法被低級權限的用戶所查看。所以我們可以在不同權限等級用戶的構造函數中,保存該用戶能夠看到的頁面。在根據權限實例化用戶。代碼如下:

JavaScript設計模式之工廠模式(Factory Method Pattern)

UserFactory就是一個簡單工廠,在該函數中有3個構造函數分別對應不同的權限的用戶。當我們調用工廠函數時,只需要傳遞superAdmin, admin, user這三個可選參數中的一個獲取對應的實例對象。你也許發現,我們的這三類用戶的構造函數內部很相識,我們還可以對其進行優化。

JavaScript設計模式之工廠模式(Factory Method Pattern)

簡單工廠的優點在於,你只需要一個正確的參數,就可以獲取到你所需要的對象,而無需知道其創建的具體細節。但是在函數內包含了所有對象的創建邏輯(構造函數)和判斷邏輯的代碼,每增加新的構造函數還需要修改判斷邏輯代碼。當我們的對象不是上面的3個而是30個或更多時,這個函數會成為一個龐大的超級函數,便得難以維護。所以,簡單工廠只能作用於創建的對象數量較少,對象的創建邏輯不復雜時使用。

工廠方法模式

工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是在JavaScript中很難像傳統面向對象那樣去實現創建抽象類。所以在JavaScript中我們只需要參考它的核心思想即可。我們可以將工廠方法看作是一個實例化對象的工廠類。

在簡單工廠模式中,我們每添加一個構造函數需要修改兩處代碼。現在我們使用工廠方法模式改造上面的代碼,剛才提到,工廠方法我們只把它看作是一個實例化對象的工廠,它只做實例化對象這一件事情! 我們採用安全模式創建對象。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼就很好的解決了每添加一個構造函數就需要修改兩處代碼的問題,如果我們需要添加新的角色,只需要在UserFactory.prototype中添加。例如,我們需要添加一個VipUser:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上面的這段代碼中,使用到的安全模式可能很難一次就能理解。

JavaScript設計模式之工廠模式(Factory Method Pattern)

因為我們將SuperAdmin、Admin、NormalUser等構造函數保存到了UserFactory.prototype中,也就意味著我們必須實例化UserFactory函數才能夠進行以上對象的實例化。如下面代碼所示

JavaScript設計模式之工廠模式(Factory Method Pattern)

在上面的調用函數的過程中, 一旦我們在任何階段忘記使用new, 那麼就無法正確獲取到superAdmin這個對象。但是一旦使用安全模式去進行實例化,就能很好解決上面的問題。

抽象工廠模式

上面介紹了簡單工廠模式和工廠方法模式都是直接生成實例,但是抽象工廠模式不同,抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。

上面例子中的superAdmin,admin,user三種用戶角色,其中user可能是使用不同的社交媒體賬戶進行註冊的,例如:wechat,qq,weibo。那麼這三類社交媒體賬戶就是對應的類簇。在抽象工廠中,類簇一般用父類定義,並在父類中定義一些抽象方法,再通過抽象工廠讓子類繼承父類。所以,抽象工廠其實是實現子類繼承父類的方法。

上面提到的抽象方法是指聲明但不能使用的方法。在其他傳統面向對象的語言中常用abstract進行聲明,但是在JavaScript中,abstract是屬於保留字,但是我們可以通過在類的方法中拋出錯誤來模擬抽象類。

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼中的getPrice就是抽象方法,我們定義它但是卻沒有去實現。如果子類繼承WechatUser但是並沒有去重寫getName,那麼子類的實例化對象就會調用父類的getName方法並拋出錯誤提示。

下面我們分別來實現賬號管理的抽象工廠方法:

JavaScript設計模式之工廠模式(Factory Method Pattern)

AccountAbstractFactory就是一個抽象工廠方法,該方法在參數中傳遞子類和父類,在方法體內部實現了子類對父類的繼承。對抽象工廠方法添加抽象類的方法我們是通過點語法進行添加的。

下面我們來定義普通用戶的子類:

JavaScript設計模式之工廠模式(Factory Method Pattern)

上述代碼我們分別定義了UserOfWechat,UserOfQq,UserOfWeibo三種類。這三個類作為子類通過抽象工廠方法實現繼承。特別需要注意的是,調用抽象工廠方法後不要忘記重寫抽象方法,否則在子類的實例中調用抽象方法會報錯。

我們來分別對這三種類進行實例化,檢測抽象工廠方法是實現了類簇的管理。

JavaScript設計模式之工廠模式(Factory Method Pattern)

從打印結果上看,AccountAbstractFactory這個抽象工廠很好的實現了它的作用,將不同用戶賬戶按照社交媒體這一個類簇進行了分類。這就是抽象工廠的作用,它不直接創建實例,而是通過類的繼承進行類簇的管理。抽象工廠模式一般用在多人協作的超大型項目中,並且嚴格的要求項目以面向對象的思想進行完成。

ES6中的工廠模式

ES6中給我們提供了class新語法,雖然class本質上是一顆語法糖,並也沒有改變JavaScript是使用原型繼承的語言,但是確實讓對象的創建和繼承的過程變得更加的清晰和易讀。下面我們使用ES6的新語法來重寫上面的例子。

ES6重寫簡單工廠模式

使用ES6重寫簡單工廠模式時,我們不再使用構造函數創建對象,而是使用class的新語法,並使用static關鍵字將簡單工廠封裝到User類的靜態方法中:

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫工廠方法模式

在上文中我們提到,工廠方法模式的本意是將實際創建對象的工作推遲到子類中,這樣核心類就變成了抽象類。但是JavaScript的abstract是一個保留字,並沒有提供抽象類,所以之前我們只是借鑑了工廠方法模式的核心思想。

雖然ES6也沒有實現abstract,但是我們可以使用new.target來模擬出抽象類。new.target指向直接被new執行的構造函數,我們對new.target進行判斷,如果指向了該類則拋出錯誤來使得該類成為抽象類。下面我們來改造代碼。

JavaScript設計模式之工廠模式(Factory Method Pattern)

ES6重寫抽象工廠模式

抽象工廠模式並不直接生成實例, 而是用於對產品類簇的創建。我們同樣使用new.target語法來模擬抽象類,並通過繼承的方式創建出UserOfWechat, UserOfQq, UserOfWeibo這一系列子類類簇。使用getAbstractUserFactor來返回指定的類簇。

JavaScript設計模式之工廠模式(Factory Method Pattern)

工廠模式的項目實戰應用

在實際的前端業務中,最常用的簡單工廠模式。如果不是超大型的項目,是很難有機會使用到工廠方法模式和抽象工廠方法模式的。下面我介紹在Vue項目中實際使用到的簡單工廠模式的應用。

在普通的vue + vue-router的項目中,我們通常將所有的路由寫入到router/index.js這個文件中。下面的代碼我相信vue的開發者會非常熟悉,總共有5個頁面的路由:

JavaScript設計模式之工廠模式(Factory Method Pattern)

當涉及權限管理頁面的時候,通常需要在用戶登陸根據權限開放固定的訪問頁面並進行相應權限的頁面跳轉。但是如果我們還是按照老辦法將所有的路由寫入到router/index.js這個文件中,那麼低權限的用戶如果知道高權限路由時,可以通過在瀏覽器上輸入url跳轉到高權限的頁面。所以我們必須在登陸的時候根據權限使用vue-router提供的addRoutes方法給予用戶相對應的路由權限。這個時候就可以使用簡單工廠方法來改造上面的代碼。

在router/index.js文件中,我們只提供/login這一個路由頁面。

JavaScript設計模式之工廠模式(Factory Method Pattern)

我們在router/文件夾下新建一個routerFactory.js文件,導出routerFactory簡單工廠函數,用於根據用戶權限提供路由權限,代碼如下

JavaScript設計模式之工廠模式(Factory Method Pattern)

在登陸頁導入該方法,請求登陸接口後根據權限添加路由:

JavaScript設計模式之工廠模式(Factory Method Pattern)

在實際項目中,因為使用this.$router.addRoutes方法添加的路由刷新後不能保存,所以會導致路由無法訪問。通常的做法是本地加密保存用戶信息,在刷新後獲取本地權限並解密,根據權限重新添加路由。這裡因為和工廠模式沒有太大的關係就不再贅述。


總結

上面說到的三種工廠模式和上文的單例模式一樣,都是屬於創建型的設計模式。簡單工廠模式又叫靜態工廠方法,用來創建某一種產品對象的實例,用來創建單一對象;工廠方法模式是將創建實例推遲到子類中進行;抽象工廠模式是對類的工廠抽象用來創建產品類簇,不負責創建某一類產品的實例。在實際的業務中,需要根據實際的業務複雜度來選擇合適的模式。對於非大型的前端應用來說,靈活使用簡單工廠其實就能解決大部分問題。

下期預告:

JavaScript設計模式之策略模式(Strategy Pattern)

如果大家有好的主題,可以在下方留言,我會準備相關的內容在後續發佈


鏈接文章:

https://zhuanlan.zhihu.com/p/37621846

https://segmentfault.com/a/1190000002525792

"

相關推薦

推薦中...