iT邦幫忙

2021 iThome 鐵人賽

DAY 30
2

終於到了最後一天了,不知道把這三十天看完的人有多少呢?希望看到最後一天的人,有感受到我對於這系列文章中想傳達出去的理念,感受到架構設計的取捨是什麼,不是只有選擇 MVP 、 MVVM 或是 Clean architecture 這種非黑即白的選項,更多的是每一個小小的選擇都會影響著程式碼的運作方式,這些選擇是為了更優雅的解決當下所碰到的問題。有碰到問題,才需要解法,程式還不夠複雜的時候,不需要因為要追求“潮流”而使用厲害的架構,相對的,還有可能因為過早的套用厲害的架構而導致後期修改的障礙。

在這系列文章中,看到了早期簡單的 MVVM ,只有一個簡單的拖拉便利貼功能,到後來功能越加越多,ViewModel 的職責漸漸多了起來,最後甚至遇到了使用單個 ViewModel 無法解決的問題,所有這一切都是慢慢發生的,在沒有過早設計的情況下,很順利的轉換到新的架構,同時這個架構也是符合產品未來的走向,在設計以及討論過程產生了 ViewPort 這個新觀念,在之後我們也利用了這個新觀念來更好的組織程式碼,在未來如果要增加平移以及放大縮小功能時,大家在第一個時間都知道這功能應該是屬於哪個元件的範疇。

對於這個產品來說,“共編器”的聚合力是非常高的,大家在討論需求或是發現 bug 時,一定第一時間就會討論它,但是如果使用比較符合潮流的 Use case 為核心的設計,“共編器”的聚合例就會大大降低,各種使用案例四散在各不同的類別中,甚至在 Domain 層還不會出現一個可以作為“共編器”的類別,只會出現像是 “刪除便利貼”、“更改便利貼顏色”、“更改便利貼位置” 這種看起來可重用度很高的 Usecase ,但是本身沒有描述到最重要的“共編器”相關領域知識,另外,像選擇便利貼這種 UI 狀態也會因為留在 ViewModel 層而造成理解上的阻礙。

Living Documentation 這本書上有一段話:『 DDD 提倡“用程式碼設計模型”作為基本的解決方案。基本想法是程式碼本身就是知識的表現。只有當程式碼不夠才需要其他東西。』。這也是我現在階段喜歡而且認同的,我相信目前的便利貼程式的架構就算是給一個非工程師來看,也大概猜得到這些元件在做什麼事。

不過!還是得要說一定有 App 非常適合以 Use case 為核心的設計,不能因為便利貼應用程式就否定了這種做法,不同的應用程式的特性有可能相差不大,也有可能天差地遠,選擇最適合該專案的架構才是最重要的,我這系列文章故意讓 Use case 看起來不好用只是想發出一個訊息:主流的架構無法套用在任何一個應用程式上,請三思而後行。

狀態(State)到底要多大?

現在還有流行著一種架構模式: MVI ,基本上就是把所有有關 UI 的狀態全部塞在一起變成一大包,而且所有的事件都只會流向同一個地方,有了這樣的架構方式,加新功能就會如同有著 SOP 準則似的一樣簡單。如果是新的事件,只要繼承自 BaseEvent 就好,並且為這個 Event 在另一個地方寫下相對應要處理的邏輯,這邊通常來說應該會是個 kotlin 的 when ,如果有新的 UI 狀態要顯示,就在 State 裡多新增一個欄位即可。正因為如此統一又好掌控,所以也受不少的開發者喜愛。

我在便利貼專案中示範的案例中,其實就有做類似的事情,有著一個相對巨大狀態,但是後來卻把這個狀態給拆掉了,這個狀態就是 allNotes 。將所有的狀態全部綁在一起最大的缺點是,即使只是更新了一個超級不起眼的數值,只佔了這個巨大狀態的不到百萬分之一,還是會因為們是綁在一起的狀態而有“連坐”的效應,很多欄位都要一起跟著複製,產生新的實例。這其實部分也是因為語言的限制,如果有一天 kotlin 正式支援 Structure sharig 的複製方式,這可能就不是一個大問題了。

關於 Structure share 可以看我去年寫的文章:https://ithelp.ithome.com.tw/articles/10247008?sc=rss.iron

所以話說回來,到底該不該把全部的狀態塞成一整包呢?這部分應該也要靠讀者自己決定了,如果專案成員都已經很熟悉這種開發模式而且不太會有效能問題的話,那這就是一種好的模式。但是如果現在開發的是一個很複雜的 feature,沒有上千行程式碼無法解決的話,我會建議你多想想,因為這種開發模式不利於建構“模型”,使用單一的巨大狀態無法好好的描述模型內各自的職責與交互關係,使用單一的事件入口也會限制了想法,最後 MVI 反而是造成技術限制的來源。

Android 工程師的價值在哪

其實我不太喜歡 Clean architecture 或是 MVI 的框架函式庫有一個原因是因為,如果這就是你的全部的工作內容的話,這樣代表你的可取代性很高,只要有新人把這套版學起來了,就可以讓新人馬上上工,老闆可以把薪水比較高的你給踢掉,反正照樣做就對了。那這時候就要想想,身為一個 Android 工程師,而且如果你還掛上一個 Senior 的 title,每天在做的工作都大同小異,接到新需求,新增一個 Usecase,開 room DB entity ,接接 API ,一個 sprint 的工作就這樣又做完了,那麼你比別人厲害的地方在哪裡呢?可能你會說,我在用最新的技術 Jetpack Compose + Flow + Room + Retrofit + Clean architecture,但是現在要是再隔個幾年,又出現更新更潮的技術(有人還記得 Airbnb 前陣子出的 MvRx 嗎?),你還要為了不被淘汰而去繼續學習這些新框架嗎?

根據我這幾年來學習的心得,以及我所觀察到的,個人覺得有高價值的工程師應該是這樣的:

  • 有著別人無法輕易學習的領域知識,例如資安、影音編輯、影像處理等等,而且一直有持續的在跟上最新資訊。
  • 有辦法快速掌握新知識,觸類旁通以及獨立思考的能力。
  • 厲害的溝通技巧,有能力掌握 stakeholder 的需求而且盡力避免掉無謂的浪費。
  • 解決複雜問題的能力,化複雜為簡單,有能力開發自己的 Glide 或是 Okhttp 這種跟“畫面”或是“流程”無關的函式庫。

致謝

很可惜的到最後沒辦法把第三階段的新功能給實作出來,但我覺得這也是好事,可以留給讀者一些想像的空間:如果是你,你會先補完測試再繼續寫新功能嗎?還有會從哪個新功能開始寫呢?

最後再次謝謝看到這裡的大家,尤其是有留言的讀者,其實我非常希望各位多留言,這樣我才能知道寫的內容有沒有人看,或是有沒有看懂,沒看懂的話,我應該用其他方式來描述才對,好拉,祝各位在未來的開發路上一切順心,人人都設計出心目中最棒的架構!

補充:其實這系列文章的內容很大一部份是啟發自我們公司 CTO 的想法,有興趣的可以看看他寫的文章:https://tech.pic-collage.com/mddv-white-paper-43c00868b8b9


上一篇
Re-architect - StickyNoteView
系列文
Jetpack Compose X Android Architecture X Functional Reactive Programming30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Jintin
iT邦新手 4 級 ‧ 2021-10-08 22:34:41

好文推,有時候也會覺得架構太多或太死反而降低了開發效率,所以不太喜歡規定一定要用什麼模式或什麼架構。

我要留言

立即登入留言