用 JavaScript 玩轉設計模式 - 你一定用過但可能不知道的 Facade Pattern(外觀模式)

Photo by Daniel McCullough on Unsplash

Hi!大家好,我是神 Q 超人!其實從去年開始,就有和一群朋友揪團讀書會在讀設計模式(如果大家有興趣加入的話也可以留言告訴我!),然後苦讀到現在總算是有累積到一些新學習的模式,能夠試著將它們輸出成文章。所以接下來要是沒其他特別想寫的東西,可能都會是設計模式的文章連發了,而且要是趕得上今年鐵人賽前把設計模式系列寫完的話,還可以再複製過去蹭個完賽獎牌。 😂

好!那前言廢話說完,讓我們來認識 Facade Pattern(外觀模式)吧!

目的

假設你現在在寫關於使用者的訂房網站,且當使用者在訂房時,你需要檢查當前使用者的資料或權限,來決定接下來要做的事情。目前要檢查的項目有這些:

1. 使用者是否登入
2. 是否已經驗證過手機
3. 是否已經驗證過信箱

所以會先有個 api query 的方法,以用來取得使用者資料的方法。在這裡會直接用 React Query 的 query hooks 寫法為例子,如果不熟 hooks 的話,在這裡就當它是個會打 api,然後回傳 api 資料的方法:

https://gist.github.com/ms314006/901e6b7da2ee981a52d3d2d66e43ffa6

至於檢查的邏輯,就交給一個 UserPermissionHandler 類別,我們會帶入使用者資料,然後讓 UserPermissionHandler 內的邏輯處理這些檢查的事情:

https://gist.github.com/ms314006/5986d8b58f8b0ef33ae710923f78a03b

接著,在檢查方面會有個 Guard 類別負責,把要檢查的資料用特定格式丟給它,並執行 execute 就能知道有沒有通過檢查:

https://gist.github.com/ms314006/1a3f861d8cc43a200056800df3f07d08

這麼一來,如果需要檢查使用者的權限,只要組合上方介紹的三個類別或方法就能達成目的:

https://gist.github.com/ms314006/5f2c5c75beca5f7343fcbcc39405ccfd

將各個行為獨立拆開(取得資料、檢查權限邏輯、檢查),得到的好處是能夠在只需要該功能時單獨使用,或是更容易地與其他行為做組合,例如:其他地方如果需要檢查某些東西,可以單獨使用 Guards 類別。壞處就是在使用時,你必須了解到它們該如何正確互動,且每次想「檢查使用者權限」都需要承擔使用三種類別或方法的複雜度。

那有辦法讓「檢查使用者權限」這件事情用起來簡單一點嗎?可以!就用 Facade Pattern!

Facade Pattern(外觀模式)

Facade Pattern 通常會在「當你想要替一些複雜的操作,提供一個簡單的使用方式」時使用。以上方的例子來說:「當我們把上方那段使用了三個類別或方法的操作封裝成一種使用方式」,那在這個情境下就等於使用了 Facade Pattern。

再延續上方的例子,其實該段程式碼最後的目標是「檢查使用者權限」,所以我們可以先建立一個空的方法,並將檢查所需要的程式碼互動都放到該方法中,讓使用端能夠直接執行該方法,以檢查使用者的權限:

https://gist.github.com/ms314006/3fe8f48dadb28d6c99e324edafe7ad11

這麼一來,當未來我們需要檢查使用者權限時,就不需要了解它內部到底組合了哪些類別或方法,只需要執行 useCheckUserPermission 就行了。

Facade Pattern 也很如其名,就是為這些東西的互動建立一個外觀,讓使用時只看到被建立的外觀,而不會分心於內部操作的複雜度。套一句在讀書會時,朋友的精闢結論:

「其實 Facade Pattern 就是封裝」

Facade Pattern 的好處不只可以讓使用上更簡單,還可以將對於該行為的變化都關在同一個地方,例如:未來需要再增加使用者是否綁定過信用卡時,就到 useCheckUserPermission 中增加邏輯,而不是全域搜尋所有「檢查使用者邏輯」相關的程式碼到處修改。

且 Facade Pattern 是將現有的類別或方法的互動封裝,因此就算不做檢查使用者權限這件事,在其他地方還是可以使用那些 Guard、useUserProfile 等類別方法。

不曉得大家看完後有什麼想法,但在當時我讀完 Facade Pattern 的時候,藉覺得我學到的其實並不是 Facade Pattern,而是發現原來一直在用的某個技巧叫做 Facade Pattern。像認識很久的朋友,不過最近才知道它名字是什麼一樣。 😂

最後如果文章裡有任何問題或是需要補充的地方,再麻煩留言告訴我,如果有看到的話,我都會盡快回覆和修改文章內容的,非常感謝! 🙌

--

--

Starbugs Weekly 星巴哥技術專欄
Starbugs Weekly 星巴哥技術專欄

Published in Starbugs Weekly 星巴哥技術專欄

一群技術人想要寫出一些好文章所建立的技術專欄。每週二一篇原創文章、一封電子報,歡迎大家訂閱!主網站: https://weekly.starbugs.dev/。

神Q超人
神Q超人

Written by 神Q超人

82 年次,單純相信努力不會騙人