鐵人賽系列文章今天進入最終章,在實作 Kimoji App 的過程,有許多實務經驗和心得非常想和各位讀者分享;Compose 的世界裡也還有許多值得探討的主題。不過我們暫且讓 30 天的鐵人賽為此系列劃下句點。未來還請各位繼續支持我的 side-project:Kimoji App。我會以 Jetpack Compose 和官方推薦的架構原則來製作有趣又有效的遊戲化工具。
此系列文章是以我的業餘專案: Kimoji 作為範例。
這款以純 Jetpack Compose 撰寫的 side project,已經在 Google Play 上架。 歡迎試玩!
立馬下載
我們來談談 Separation of Concerns。在 30 天的文章中,我們大致可以領略如何用 Compose 來實作 UI 邏輯。但我們也可以合理地問,這樣的設計,在實務上有沒有 follow Separation of Concerns 的原則?Separation of Concerns 有時候可以從 “Coupling” 和 “Cohesion” 的角度來思考。而且這有助於理解和分辨。
抽象來說,當我們寫 code 的時候,會從模組的角度來看我們的程式。 每個模組裡面可能都有一些 units。
Coupling 指的是:不同 module 中的 units 彼此之間的相依關係。另一種思考方式是,我在一個 module 某處改東西,其他 module 的某些東西也需要跟著改。通常來說,我們想要減少或最小化程式裡面的 coupling。但有時候,耦合的發生可能是不明確的,例如一些間接的相依關係。這意味著當我們改某些東西的時候,結果其他東西會壞掉。有時候如果我們沒有工具來識別這種情況的話,狀況就會很糟。
另一個相反的概念是 Cohesion。Cohesion 就是「將功能相關的 units 組合成一個 module 的程度」,或是「各個 units 聚集的程度」。通常來說, cohesion 是一件好事,我們想要最大化 cohesion。
Separation of Concern 可以想成是儘量把相關的 code 組合在一起,劃出分界線,讓耦合最小化。藉此讓我們的程式更容易被維護和擴充。
所以,我們用實務上 Android 開發的例子來形容這個概念。假設我們有個 layout XML 和它對應的 Activity。
Activity 會把 layout inflate 出來,處理一些互動之類的東西。所以,他們兩者之間可能隱藏著許多相依關係,會有大量的耦合。Activity 需要知道 layout 裡面的東西,而這可以透過很多方法來達成。比較常見的做法就是 findViewById
。
有時候還會有比較複雜的操作,Activity 就需要知道這份 layout 的結構,兩者之間就建立了耦合關係。當我們的 app 開始成長時,這些相依關係也會跟著成長。
當然,我們會想要盡可能的把 UI 邏輯拉出 Activity 外。我們可能會用 ViewModel 和 DataBinding 來達到這件事。
但這樣做其實沒辦法真正消除任何的耦合性,它只是把耦合轉嫁到 ViewModel 身上。最後,ViewModel 的職責會和 layout 非常相關。 因此 ViewModel 可能會需要知道 layout 上的東西。(例如某顆按鈕的 visibility)
這裡最主要的問題之一,就是 UI 相關的邏輯是用一種語言寫的,而 layout 本身是用另外一種語言去定義。 這造成了強制的區分。也因為他們被迫用不同的語言去寫,這就會導致不明確的耦合性發生。
所以想法是,我們如果用同一個語言來定義 UI,那至少這些相依關係可以變得更加明確。
如果我們使用 Composable function 來定義 layout,我們就可以充分發揮 Kotlin function 的功能,去實踐 Separation of Concerns 的原則。這代表一些高度耦合的邏輯可以被重構,結果就是我們的 code 會有更少耦合,和擁有更多的內聚。
無論 app 的架構如何設計,我們都會需要在 app 中處理與 UI 相關的邏輯。Framework 本身無法改變這一點。但 framework 可以做的是為我們提供像 Composable function 這樣的工具,讓我們可以更容易在程式中,運用 functions 來切分職責。
此系列文章是以我的業餘專案:Kimoji 為範例。
Kimoji 是一款心情日記 App,讓你用可愛的 emoji 來撰寫你的心情日記。現在就來試試這款設計精美的微日記吧!
立馬下載
Reference: https://medium.com/androiddevelopers/understanding-jetpack-compose-part-1-of-2-ca316fe39050