Day 16- 老生常談的組合取代繼承
在昨天的例子中,我們談論到使用樣板模式來建立 PlatformWidget,並讓子類別實作 buildMaterial 與 buildCupertino,實現不同平台不同樣式的設計。但是在實際開發中,並非只有 Widget 有可能有多平台的設計,有些時候,我們的商業流程可能也會與平台相關。
流程處理也分平台
假設我們今天有應用程式內購需求,在 Android 與 iOS 的內購流程可能不盡相同,此時,我們會在 InAppPurchaseService 中,加入平台的判斷,讓相同的方法使用不同的流程。同時也有些畫面顯示也需要根據平台顯示不同樣式。

在上面這段例子中,我們可以發現裡頭的平台判斷,與昨天 PlatformWidget 中的判斷一致,但此時我們卻無法繼承 PlatformWidget 來重複利用這段程式碼。原因想必聰明的讀者一定知道,因為我們的 InAppService 並不是一個 Widget,讓他繼承 PlatformWidget 顯然不合理。那我們如何解決這個問題呢?
使用組合取代繼承
所幸 Dart 除了繼承之外,還有提供 Mixin,讓我們可透過組合其他類別的方式,來利用相同的邏輯。以下就讓我們使用 Mixin 建立一個判斷平台的方法吧。

透過使用 Mixin,我們利用組合的方式,將判斷平台的邏輯使用在原本的 HomeScreen 和非 Widget 的類別,以下面的例子來說,InAppPurchaseService 也能使用 handleByPlatform 處理不同平台的購買流程。

相比於繼承來說,組合要更加來的有彈性。在 Flutter 中,Widget 有時候可能不是繼承 StatelessWidget,此時原本設計的 PlatformWidget 就變得不那麼實用。相反的,如果使用組合的方式,我們就能把判斷平台的邏輯在需要的地方使用,而不會被繼承所受限。
用 Widget 來組合
在昨天的例子中,我們讓 MyInfoScreen 繼承 PlatformWidget,並實作 buildMaterial 和 buildCupertino,解決達到不同平台不同樣式的問題。但是其實這個問題,同樣可透過組合 Widget 的方式解決。讓我們修改一下昨天的例子,看看會有什麼不同。

若我們今天只有畫面需要判斷,單純使用組合 Widget 的方式,也能達到控制流程的效果,並不是一定要抽成 Mixin 或使用繼承。
結論
大多數時候,當我們只想共用的時候,可已先嘗試使用組合法方式解決問題。運用組合,每個物件可以任意挑選自己想要的元件或模組來重用。同樣的不同平台不同畫面的問題,我們同樣可以透過組合方式解決,讓設計可以更有彈性。
— 全文完 —
如果這篇對你有幫助,可以分享給朋友,或追蹤後續更新。我在 Threads 也會貼一些零碎想法。