[Design Pattern] 工廠方法(Factory Method)

Andy Lu
5 min readJan 29, 2021

用 Kotlin 示範

攝影師:Movidagrafica Barcelona,連結:Pexels

目的

在子類別上決定要如何具現類別的物件。

模式

建立型模式 (Creational Pattern)

時機

在多個相似的類別中,依照需求建立出同一介面的物件。(創建步驟可能不同,也有可能是參數不同…)

步驟

將建立物件的方法 (factory method) 抽出至父類別或是介面中,這些相似的子類別,只需要繼承父類別,並覆寫建立物件的方法。

範例

有兩個類別 HDCameraRecorderCreator 以及 CameraRecorderCreator,分別建立高畫質的 CameraRecorder (HDCameraRecorder) 以及普通畫質的 CameraRecorder (CameraRecorder)。

其中 CameraRecorder 以及 HDCameraRecorder 都是實作 ICameraRecorder 的物件。

我們注意到, ICameraRecorder 是設定為 lateinit (延遲初始化) 且在 record() 中才被實例化。

操作步驟

  1. 抽取方法 (Extract Method)
  • 將實例化 ICameraRecorder 的部分抽成一個名為 createCameraRecorder 的方法,也就是 factory method (工廠方法)。
  • 其中, createCameraRecorder 的回傳型別為 ICameraRecorder

2. 抽出父類別 (Extract Superclass)

CameraRecorderCreatorHDCameraRecorderCreator 中的 factory method: createCameraRecorder() 抽出至父類別 AbstractCameraRecorderCreator

AbstractCameraRecorderCreator

3. 繼承父類別

  • CameraRecorderCreatorHDCameraRecorderCreator 繼承 AbstractCameraRecorderCreator
  • CameraRecorderCreatorHDCameraRecorderCreator 中的 createCameraRecorder 就要加上 override修飾符
Extends superclass

4. 將 lateinit var cameraRecorde: ICameraRecorder 也搬到父類別中。

Move interface of object to superclass

5. 我們發現, record() 也可以搬到父類別中,因為在兩個類別中所做的動作都相同。

  • record() 搬到父類別後, cameraRecorder 的訪問修飾符 (Access Modifier) 就能改成 private

6. 完成

在子類別呼叫 createCameraRecorder() 來決定要建立哪一個類別。

優點與缺點

+子類別利用 factory method 可以依照類別的需求建立不同的物件 (相同介面)。

+在父類別中,把可重複利用的項目保留在父類別中,如 record() ,如此就可以減少子類別重複的內容。

— 如果建立物件需要不同的參數,在 factory method 就會包含所有的參數,縱使子類別不需要。

心得

factory method 是最容易的 Design Patterns,雖然容易,但也很重要。

為了要使 factory method 能應用在不同的類別,我們必須要將物件共同的內容抽出成介面。在不同的類別呼叫時,我們就可以回傳其介面而不是實作。

Program to an interface, not an implementation
Design Patterns - GoF

以前都是直接回傳其實作,用 factory method 之後,就可以限制我們回傳實作這個動作。

回傳介面的好處,對於程式未來的擴展性是更高的,因為如果有類似的類別,我只要實作該介面,並且令某一子類別實作該類別即可。

你覺得我這次分享的還不錯,幫我按拍手 👏 給我鼓勵吧~

github: https://github.com/andyludeveloper/factory_method_in_kotlin

--

--

Andy Lu
Andy Lu

Written by Andy Lu

Android/Flutter developer, Kotlin Expert, like to learn and share.

Responses (1)