iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0
Software Development

從 Vibe Coding 到可維護專案:用 Hermes Agent 重讀 RoomRush Android 專題系列 第 28 篇

Day 28 | 重讀 27 天後,我畫出了 RoomRush 的專案總地圖

  • 分享至 

  • xImage
  •  

前言:使用者查詢、資料來源、管理者維護如何合成一張圖?

前面花了這麼多天,我已經看過 MainActivity、ViewModel、Repository、DAO、AppDatabase等檔案,也追過使用者查詢和管理者修改資料的流程。

但如果現在把程式碼全部關掉,只問我一個問題:**「RoomRush 到底是怎麼運作的?」**我能不能不用重新翻檔案,就把它講清楚?

這也是我在第 28 天想做的事情:把前面拆開看的東西重新組起來,畫出 RoomRush 的專案總地圖。


我原本看到的是檔案,現在看到的是關係

如果要我用一句話介紹 RoomRush,我會說:

RoomRush 是一個以 ClassroomSchedule 課表資料為核心,讓一般使用者查詢空教室,也讓管理者維護課表與教室資訊的 Android App。

這句話看起來很簡單,但其實是我重新讀完專案之後才比較能說出口的。
因為一開始我看到的是一個個 Kotlin 檔案,像是 MainActivity.kt、QueryResultViewModel.kt、AppDatabase.kt、ClassroomScheduleDao.kt……
當時比較像是知道這個檔案在做什麼,卻不一定知道它和其他檔案為什麼會連在一起。

重新追過資料流之後,我開始發現,這些檔案其實都圍繞著同一件事情:教室課表資料怎麼進來、怎麼被查詢、怎麼被修改,以及最後怎麼顯示給使用者。


RoomRush 的專案總地圖

                     RoomRush
                        │
          ┌─────────────┴─────────────┐
          │                           │
       資料來源                      App 功能
          │                           │
    SF.csv / ES.csv             ┌─────┴─────┐
          │                     │           │
          ▼                     ▼           ▼
 AppDatabase.parseCsv()      使用者功能    管理者功能
          │                     │           │
          ▼                     │           ▼
  ClassroomSchedule             │      LoginActivity
          │                     │           │
          ▼                     │           ▼
   Room Database                │      ManagerActivity
          │                     │           │
    ┌─────┴─────┐               │     ┌─────┼─────┐
    ▼           ▼               │     ▼     ▼     ▼
   DAO      Repository          │   課表   教室   教室
    │           │               │   管理   設定   狀態
    └─────┬─────┘               │
          │                     │
          ▼                     │
      ViewModel                 │
          │                     │
          ▼                     ▼
          UI              空教室 / 詳細資訊

真正專案核心:ClassroomSchedule

把整個專案串起來之後,我發現最值得注意的其實不是哪一個 Activity,而是 ClassroomSchedule。

它代表的是一間教室的一週課表與教室資訊:

ClassroomSchedule
├── classroom:教室名稱,例如 SF304
├── mon1 ~ fri8:一週課表時段
└── classroomType:教室類型,例如 Normal / Computer / Lab

不同功能線其實都在使用同一份 ClassroomSchedule,只是使用角度不同:

功能 怎麼使用 ClassroomSchedule
查詢空教室 判斷指定時段是否 != "X"
課表管理 將時段修改成 X 或 null
教室詳細設定 修改 classroomType
完整課表 找出 == "X" 的時段

這也讓我重新理解之前在 Day 9 | 我終於搞懂:在這個專案裡,X 不是空教室
花了一篇文章討論的 X,
以及在 Day 25 | 完整課表頁為什麼顯示的是有課時段,而不是空教室?
有補充到使用者和管理者會看到的差別。

X 的意思其實沒有因為不同頁面而改變,它一直代表「這個時段有課/被佔用」。
差別只是不同功能想回答的問題不同:

  • 查空教室:我要找「不是 X」的教室。
  • 管理課表:我要把某個時段設成 X 或取消 X。
  • 看完整課表:我要列出「是 X」的時段。

同一份資料,因為使用情境不同,而產生不同的查詢方式。


三條功能線,其實都回到同一份資料

1. 一般使用者:查詢教室

MainActivity
		↓
QueryResultActivity
		↓
QueryResultViewModel
		↓
篩選 ClassroomSchedule
		↓
EmptyRoomAdapter
		↓
空教室列表
		↓
RoomDetailActivity

2. 管理者:維護資料

LoginActivity
		↓
ManagerActivity
		│
		├── 課表管理
		│
		├── 教室設定
		│
		└── 教室狀態
		↓
Repository → DAO
		↓
Room Database

3. 資料來源:提供這些功能需要的資料

SF.csv / ES.csv
        ↓
AppDatabase.parseCsv()
		↓
ClassroomSchedule
		↓
Room Database
		↓
DAO
		↓
Repository
		↓
各功能的 ViewModel

看起來這是三條不同的功能,但它們最後都圍繞著同一份 ClassroomSchedule 資料。這也是我重新畫完總圖之後,才比較清楚看到的關係。


我也重新看懂 Day 17 的問題

當我把這些流程放在同一張圖上時,前面 Day 17 | 我發現一個危險問題:管理者修改可能被 CSV 蓋掉
發現的 CSV 覆蓋問題,也變得更容易理解。

原本我只看到:

CSV → Room Database

但現在把管理者功能也放進來後,就會變成:

SF.csv / ES.csv
        ↓
Room Database
        ↑
        │
	管理者修改

這兩條路徑其實都在操作同一份資料;所以問題就不只是「onOpen() 為什麼會重新匯入 CSV」,而是:當 CSV 和管理者修改都可以成為資料來源時,到底誰才是這份資料的真正來源?

這也是我到後面才發現,原本以為只是初始化資料的 CSV,其實牽涉到整個 App 的資料生命週期。


Hermes Agent 如何協助我畫出這張圖

前幾天使用 Hermes Agent 時,我比較常問的是「這個檔案在做什麼?」或「這個方法的資料從哪裡來?」

到了第 28 天,我問的問題開始不太一樣。我不再只想知道單一檔案,而是要求它把不同功能的流程放在一起比較:

  • 使用者查詢空教室時,資料從哪裡來?
  • 管理者修改資料時,又經過哪些層?
  • ClassroomSchedule 在不同功能中扮演什麼角色?
  • 哪些功能最後會回到同一個 DAO / Repository?

Hermes 可以很快幫我整理出這些關係,但我沒有直接把它產生的架構圖當成答案。

我還是需要回到實際程式碼或是前面所整理的筆記,確認每一條連線的連結。例如 Activity 傳了什麼 Intent、ViewModel 從哪裡取得 Repository、Repository 實際呼叫哪個 DAO 方法。


小結

整理完整個 RoomRush 專案後,我發現它的核心其實不是某一個畫面,而是一份 ClassroomSchedule 資料。這份資料從 SF.csv 和 ES.csv 匯入 Room Database,經過 DAO 和 Repository,再被不同 ViewModel 提供給畫面使用。

一般使用者看到的是查詢空教室流程:從首頁選大樓,到查詢頁選星期、節次與樓層,最後由 QueryResultViewModel 篩出不是 X 的教室。

管理者看到的是另一面:登入後台後,可以修改某間教室某時段是否有課、修改教室類型、新增教室,或查看每間教室完整的有課時段。

讀完這個專案後,我對 X 的理解也變得更清楚。X 固定代表有課或被佔用,但不同頁面會用不同角度看它。查詢空教室時,程式找的是不是 X;管理者修改課表時,選「是」會寫入 X;完整課表頁則只列出等於 X 的有課時段。

這個專案也暴露出一些工程上的取捨。像是 CSV 每次開啟資料庫時重新匯入,可能覆蓋管理者修改;管理者帳密硬編碼不安全;是否可飲食不是獨立欄位;大樓代碼與時間表硬編碼;以及部分檔案命名不一致。這些不是讓 App 不能運作的錯誤,但很適合作為後續改善清單。


下一篇預告:技術債不是批評:這是我看懂專案後整理出的工程觀察

整個空教室查詢系統的操作大致上了解之後,我們在這過程中也提到很多這 App 的缺點。

下一篇我們會一一攤開這些技術債,了解哪些是在真正開發 App 時最需要改良的地方,哪些部分是可以未來可再擴充的功能,並衡量這些改善是否會增加風險?


上一篇
Day 27 | 不是每個檔案都要深讀:我如何判斷主流程與支援檔案?
系列文
從 Vibe Coding 到可維護專案:用 Hermes Agent 重讀 RoomRush Android 專題 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言