iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Software Development

從 Fragment 到 Compose — 老 Android App 重寫的架構取捨系列 第 16 篇

Day 16|Use case 層要不要:排序與篩選規則該放哪裡

  • 分享至 

  • xImage
  •  

動筆前先答(兩題)

1.【決策邊界|架構論述】 舊的任務列表把「怎麼排序、哪些要顯示」的規則寫在一個 1,700 行的 ViewModel 裡。重寫時有三種放法:留在新的 ViewModel 裡;抽成一個不依賴任何東西的純函式;做成一個注入 repository 的 use case 類別。考慮下面三種情況,各自在什麼條件下,你會從「留在 ViewModel」改選另外兩種?改了之後多付出的代價是什麼?

  • 同一套排序規則,列表畫面、地圖畫面、手動排序畫面都要用。
  • 規則要同時看任務資料和「使用者今天的出勤狀態」,這兩份資料來自不同的 repository。
  • 規則只有一個畫面用,而且只有兩行。

最後判斷:如果團隊規定「每個 ViewModel 都必須透過 use case 取資料,不能直接碰 repository」,你會支持還是反對?什麼樣的專案會讓你改變立場?

我的回答:(待補)

2.【預測再驗證|測試與品質】 排序規則是「急件排前面;同樣急的依時段由早到晚;沒有指定時段的排在同組最後」。下面三種寫法,排出來的 id 順序各是什麼?

data class Task(val id: Int, val urgent: Boolean, val slot: Int?)   // slot:時段,null 表示沒有指定

val tasks = listOf(
    Task(1, urgent = false, slot = 2),
    Task(2, urgent = true,  slot = null),
    Task(3, urgent = false, slot = null),
    Task(4, urgent = true,  slot = 1),
    Task(5, urgent = false, slot = 2),
)

val a = tasks.sortedWith(compareByDescending<Task> { it.urgent }.thenBy { it.slot })
val b = tasks.sortedWith(compareByDescending<Task> { it.urgent }.thenBy(nullsLast<Int>()) { it.slot })
val c = tasks.sortedBy { it.slot }.sortedByDescending { it.urgent }

先寫下 a、b、c 的預測與理由,再寫單元測試驗證。哪一種符合規則?第 1 筆和第 5 筆的條件完全相同,它們的先後有沒有保證?依據是什麼?

驗證完再想一層:你剛才寫的測試,如果這段規則是寫在 ViewModel 的 combine 裡面,測試要多準備哪些東西才跑得起來?如果是一個純函式呢?這個差別會不會影響你對第 1 題的答案?

我的回答:(待補)


上一篇
Day 15|拖曳排序:樂觀更新與回滾
下一篇
Day 17|硬體抽象:把藍牙磅秤包成 Flow
系列文
從 Fragment 到 Compose — 老 Android App 重寫的架構取捨 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言