2026/06/07

把「架構透視能力」整合進任何專案的設計說明


0. 核心觀念

一個專案之所以難維護,通常不是因為程式碼不夠多,而是因為「人看不見系統真正的結構」。

程式碼表面上是檔案、資料夾、函式、class、API、config、SQL、test、README。
但真正影響維護成本的是:

  • 哪些模組彼此依賴

  • 哪些命名反映真實業務語意

  • 哪些邏輯是核心流程

  • 哪些檔案只是輔助工具

  • 哪些變更會連帶影響其他區塊

  • 哪些架構規則被破壞

  • 哪些知識只存在某個工程師腦中

因此,專案管理的第一原理不是「寫更多文件」,而是:

讓系統的結構、語意、依存、責任邊界與變更影響可以被持續看見。

Understand-Anything 這類工具的價值,不只是「把 code 畫成圖」,而是提供一套方法:
把 codebase 從文字集合轉換成可搜尋、可導航、可審查、可解釋的知識圖譜。


1. First Principle 拆解:任何專案都必須回答的 6 個問題

問題 1:這個專案有哪些「東西」?

最基礎的單位不是檔案,而是「可被理解的實體」。

一個專案至少包含:

  • File:檔案

  • Module:模組

  • Function:函式

  • Class / Type:類別或型別

  • API endpoint:外部介面

  • Database table / model:資料結構

  • Job / worker:背景任務

  • Config:設定

  • Test:測試

  • Domain concept:業務概念

  • Flow:流程,例如登入、付款、搜尋、同步、匯入

工具要做的第一件事,是把專案拆成這些節點。

這會讓專案從:

一堆檔案

變成:

一組有語意的系統元件

問題 2:這些東西之間有什麼關係?

理解專案的關鍵不是「知道有哪些檔案」,而是知道它們如何互相連動。

常見關係包括:

  • A imports B

  • A calls B

  • A extends B

  • A implements B

  • A reads from table X

  • A writes to table Y

  • API A triggers service B

  • Service B publishes event C

  • Job C updates model D

  • Test T covers function F

  • Component X renders component Y

這些關係組成專案的依存圖。

一旦依存圖存在,就能回答:

  • 修改這個函式會影響誰?

  • 哪些模組耦合太高?

  • 哪些檔案是核心節點?

  • 哪些 API 其實依賴了資料層細節?

  • 哪些 utility 被太多地方共用,導致風險很高?

  • 哪些功能沒有測試覆蓋?


問題 3:每個東西的責任是什麼?

程式碼可以被 parser 分析,但「意圖」需要語意解釋。

例如:

user.ts
auth.ts
session.ts
token.ts

這些檔名看似清楚,但仍然需要知道:

  • user.ts 是資料模型、業務邏輯,還是 API controller?

  • auth.ts 負責登入、授權,還是 token 驗證?

  • session.ts 管理 client session,還是 server-side session?

  • token.ts 是 JWT、OAuth token,還是 internal access token?

因此,每個節點都應該有一段簡短說明:

這個模組負責驗證使用者登入狀態,讀取 access token,驗證過期時間,並回傳目前使用者的權限範圍。

這種摘要不是裝飾,而是降低 onboarding、code review、debugging、重構成本的基礎設施。


問題 4:這些東西屬於哪一層?

好的架構必須有層次。

常見層級包括:

UI Layer
API Layer
Application / Service Layer
Domain Layer
Data Access Layer
Infrastructure Layer
Utility Layer
Test Layer
Configuration Layer

每個檔案或模組都應該能被歸類。

歸類之後,就可以檢查架構規則:

  • UI 不應該直接碰 database

  • API controller 不應該塞滿 business logic

  • Domain logic 不應該依賴 framework

  • Utility 不應該反向依賴 service

  • Data layer 不應該呼叫 presentation layer

  • Test helper 不應該被 production code 使用

換句話說,架構不是靠口頭約定,而是靠「可觀測的分層與依存規則」維持。


問題 5:從業務角度,這些程式碼代表什麼流程?

工程師看的是 function。
使用者和產品看的是流程。

例如:

login()
validatePassword()
createSession()
setCookie()
redirectToDashboard()

從 code 角度是五個函式。
從業務角度是一個「登入流程」。

專案應該能把低階 code map 到高階業務流程:

使用者登入流程
1. 接收 email / password
2. 查詢使用者
3. 驗證密碼
4. 建立 session
5. 寫入 cookie
6. 導向 dashboard

這個 mapping 非常重要,因為它讓工程、產品、QA、資安、維運可以用同一張地圖討論系統。


問題 6:當我修改某個地方,會影響什麼?

維護專案最痛苦的地方是「看不見變更影響」。

理想狀態下,每次 PR 或 commit 前都應該能回答:

  • 這次改動碰到哪些節點?

  • 這些節點被誰依賴?

  • 哪些 API 可能受影響?

  • 哪些測試應該重跑?

  • 哪些文件需要更新?

  • 是否破壞架構分層?

  • 是否新增循環依賴?

  • 是否讓命名與責任邊界變模糊?

這就是架構透視工具最適合被整合進開發流程的地方。


2. 把工具能力抽象成通用框架

Understand-Anything 的核心能力可以抽象成五層。

Layer 1:Scan 掃描層

目的:建立專案的原始地圖。

要掃描的內容:

  • 檔案路徑

  • 語言與框架

  • import / export

  • function / class / type

  • API routes

  • database schema

  • config

  • test files

  • markdown docs

  • package dependencies

輸出:

{
  "nodes": [],
  "edges": [],
  "metadata": {}
}

這一層應該盡量使用 deterministic parser,例如 AST parser、Tree-sitter、language server、framework metadata。
因為它需要準確,不應該完全依賴 LLM 猜測。


Layer 2:Analyze 分析層

目的:判斷每個節點的用途、責任與語意。

分析內容:

  • 這個檔案做什麼?

  • 主要輸入是什麼?

  • 主要輸出是什麼?

  • 它依賴誰?

  • 誰依賴它?

  • 它是核心邏輯還是輔助邏輯?

  • 它的命名是否準確?

  • 它是否過度承擔責任?

輸出範例:

{
  "id": "src/auth/session.ts",
  "type": "file",
  "layer": "service",
  "summary": "管理登入後的 session 建立、驗證與失效。",
  "responsibilities": [
    "create session",
    "validate session",
    "expire session"
  ],
  "risk": "high",
  "reason": "被 API middleware 和 user permission flow 同時依賴"
}

Layer 3:Architecture 分層層

目的:讓系統的邊界可視化。

每個節點要被標註:

  • layer

  • domain

  • owner

  • stability

  • complexity

  • risk level

  • public / private API

  • internal / external dependency

建議標準:

Layer:
- presentation
- api
- application
- domain
- data
- infrastructure
- utility
- test
- config

Risk:
- low
- medium
- high
- critical

Stability:
- experimental
- active
- stable
- deprecated

架構圖不是只給人看的,也要能用於規則檢查。

例如:

Rule 1: presentation layer cannot import data layer directly.
Rule 2: domain layer cannot depend on framework-specific modules.
Rule 3: utility layer cannot depend on application services.
Rule 4: deprecated modules cannot be imported by new modules.

Layer 4:Explain 解釋層

目的:讓專案能自我說明。

每個重要節點都應該能回答:

  • 它是什麼?

  • 它為什麼存在?

  • 它如何被呼叫?

  • 它依賴什麼?

  • 修改它要小心什麼?

  • 有哪些相關測試?

  • 常見錯誤是什麼?

  • 新人應該先看哪裡?

輸出不應該是冗長文件,而是可點擊、可搜尋、可逐步展開的說明。

好的說明格式:

Purpose:
這個 service 負責使用者登入後的 session 生命週期。

Inputs:
- userId
- accessToken
- refreshToken

Outputs:
- session object
- cookie payload

Depends on:
- UserRepository
- TokenValidator
- SessionStore

Used by:
- login API
- auth middleware
- logout API

Change warning:
修改 session 結構時,需同步檢查 cookie parser、middleware、logout flow 與 e2e tests。

Layer 5:Review / Maintain 維護層

目的:讓架構可以持續維護,而不是一次性分析。

每次開發時應該檢查:

  • 新增了哪些節點?

  • 移除了哪些節點?

  • 哪些依存關係改變?

  • 是否出現循環依賴?

  • 是否有命名不一致?

  • 是否有責任過大的模組?

  • 是否有架構層級違規?

  • 是否有沒有測試的核心邏輯?

  • 是否需要更新 onboarding guide 或架構圖?

這一層應該與 PR review、CI、pre-commit、release checklist 整合。


3. 如何把這套能力整合進任何專案

Step 1:建立專案知識圖譜

每個專案都應該產出一份 machine-readable 的結構資料。

建議檔案:

.project-intelligence/
  graph.json
  architecture.json
  domains.json
  naming-rules.md
  onboarding.md
  dependency-report.md
  change-impact-report.md

其中 graph.json 是核心資料,其他文件都可以由它延伸。


Step 2:定義命名規範

命名不是美感問題,而是認知成本問題。

一個好的名稱應該回答三件事:

它是什麼?
它負責什麼?
它屬於哪一層?

檔案命名原則

不好:

helper.ts
utils.ts
common.ts
manager.ts
processor.ts
service.ts
data.ts
main.ts

較好:

validateUserSession.ts
createCheckoutSession.ts
calculateInvoiceTotal.ts
parseSearchQuery.ts
syncCustomerProfileJob.ts

函式命名原則

函式名稱應該使用動詞開頭:

getUserById()
createSession()
validateAccessToken()
calculateDiscount()
syncInventory()
parseWebhookPayload()

避免模糊動詞:

handle()
process()
doStuff()
run()
execute()
manage()

除非該函式所在上下文非常明確。

Class / Service 命名原則

Service 名稱應該描述責任,而不是技術實作。

不好:

UserManager
DataProcessor
CommonService
MainService

較好:

UserRegistrationService
SessionValidationService
PaymentReconciliationService
SearchIndexingService

Boolean 命名原則

Boolean 應該像問題。

isActive
hasPermission
canRetry
shouldRefreshToken
requiresApproval

不要用:

active
permission
retry
flag
status

Event 命名原則

Event 應該描述已發生的事。

UserRegistered
PaymentCaptured
OrderCancelled
PasswordResetRequested
SearchIndexUpdated

不要用:

RegisterUser
CapturePayment
CancelOrder

因為那比較像 command,不像 event。


Step 3:建立架構分層規則

每個專案應該明確定義哪些層可以依賴哪些層。

範例:

UI → API Client → Application Service → Domain → Repository → Database

允許:

api imports service
service imports domain
service imports repository
repository imports database client
test imports anything needed for testing

禁止:

ui imports database
domain imports api
domain imports framework
repository imports ui
utility imports service

這些規則應該寫進:

architecture-rules.md

並盡量用工具檢查。


Step 4:建立依存圖檢查

每個專案應該定期產生 dependency report。

報告至少包含:

1. Top imported modules
2. Circular dependencies
3. High fan-in nodes
4. High fan-out nodes
5. Orphan files
6. Deprecated modules still in use
7. Test coverage gaps
8. Cross-layer violations

解釋:

  • fan-in 高:很多地方依賴它,修改風險高

  • fan-out 高:它依賴很多東西,責任可能過大

  • circular dependency:架構邊界不清

  • orphan file:可能是死 code 或未被使用的功能

  • cross-layer violation:違反分層設計


Step 5:把 AI 解釋變成專案資產

AI 不應該只在聊天視窗裡回答一次問題。
它產生的高品質解釋應該沉澱成專案資產。

建議保存:

docs/architecture/
  overview.md
  domain-map.md
  dependency-map.md
  onboarding-guide.md
  critical-flows.md
  change-risk-guide.md

每次重大變更後更新:

  • 架構圖

  • 核心流程

  • domain map

  • onboarding guide

  • high-risk modules list

  • naming examples


Step 6:導入 PR Review Checklist

每個 PR 都應該檢查架構與可讀性,而不只是功能正確。

範例 checklist:

Naming
- 新增名稱是否清楚描述責任?
- 是否出現 helper、utils、manager、common 等模糊名稱?
- Boolean 是否使用 is / has / can / should / requires?
- Event 是否使用過去式?

Architecture
- 是否遵守分層規則?
- 是否有 UI 直接依賴 data layer?
- 是否讓 domain layer 依賴 framework?
- 是否產生新的循環依賴?

Responsibility
- 新增模組是否只做一件主要事情?
- 是否有函式過長或 service 過度膨脹?
- 是否應該拆成 domain、service、repository?

Dependency
- 是否新增高風險 dependency?
- 是否讓核心模組依賴不穩定模組?
- 是否有不必要的 shared utility?

Maintainability
- 是否有測試覆蓋核心邏輯?
- 是否需要更新文件?
- 是否需要更新 onboarding 或 architecture map?
- 是否能用工具看出 change impact?

4. 用這套框架提升專案品質的具體技巧

技巧 1:把「讀不懂」視為 design smell

當新人或 AI 看不懂某段 code,不要只怪讀者。
那可能代表命名、邊界或依存設計有問題。

常見 smell:

檔名太泛
函式太長
責任混雜
資料流不明
命名與實際用途不符
utility 過度膨脹
service 變成上帝物件

修正方式:

重新命名
拆分責任
補上摘要
建立明確輸入輸出
把 domain concept 拉出來
補上測試與範例

技巧 2:每個核心流程都要有 Flow Map

例如登入流程:

LoginPage
  → POST /api/login
  → AuthController.login
  → AuthService.validateCredentials
  → UserRepository.findByEmail
  → PasswordHasher.compare
  → SessionService.createSession
  → CookieWriter.setSessionCookie

這種 flow map 比單純文字文件更有價值,因為它能對應到實際程式碼節點。

每個專案至少應該維護:

登入流程
註冊流程
付款流程
搜尋流程
資料同步流程
錯誤處理流程
權限檢查流程
部署流程

依專案類型調整。


技巧 3:把核心邏輯和框架邏輯分開

不好的設計:

API handler 裡同時做:
- parse request
- validate permission
- query database
- calculate business rule
- send email
- format response

好的設計:

API handler:
- parse request
- call application service
- return response

Application service:
- coordinate use case

Domain:
- business rule

Repository:
- data access

Infrastructure:
- email, queue, external API

這樣知識圖譜會更乾淨,AI 也更容易解釋專案。


技巧 4:不要濫用 shared / common / utils

utils 是很多專案架構腐化的起點。

當一個 utility 被很多地方依賴,它會逐漸變成:

誰都可以放
誰都不負責
誰都不敢改

建議:

src/shared/date/formatDate.ts
src/shared/money/calculateTax.ts
src/auth/validateAccessToken.ts
src/search/parseSearchQuery.ts

比:

src/utils.ts
src/common.ts
src/helpers.ts

更容易維護。


技巧 5:用圖譜找出重構優先順序

不需要憑感覺決定先重構哪裡。

優先處理:

1. 高 fan-in 且低可讀性的模組
2. 高 fan-out 的 service
3. 循環依賴
4. 命名模糊但位於核心流程的檔案
5. 沒有測試的 high-risk node
6. 跨層依賴違規
7. 被多個 domain 共用但沒有清楚 ownership 的模組

這讓重構從主觀偏好變成客觀決策。


技巧 6:讓 AI 先讀圖,再讀 code

不要讓 AI 一開始就亂讀整個 repo。

比較好的順序:

1. 先產生 knowledge graph
2. 先看 architecture overview
3. 找到相關 domain / flow
4. 再打開相關檔案
5. 最後才要求 AI 修改 code

這樣可以避免 AI context 爆掉,也能降低它誤讀專案的機率。


技巧 7:把 change impact 放進開發流程

每次修改前問:

這次改動會碰到哪些節點?
這些節點被誰依賴?
是否需要更新測試?
是否破壞架構規則?
是否影響核心流程?

每次修改後問:

新增了哪些依存?
移除了哪些依存?
是否產生新的高風險節點?
文件是否失效?
onboarding guide 是否需要更新?

這能顯著降低「改 A 壞 B」的風險。


5. 適用於任何專案的導入模板

Phase 1:建立可見性

目標:知道專案有哪些東西。

任務:

- 掃描 file / function / class / dependency
- 建立 graph.json
- 標記核心模組
- 標記高風險模組
- 建立初版 dashboard 或 dependency map

完成標準:

任何新人都能在 30 分鐘內知道專案主要入口、核心流程與高風險區域。

Phase 2:建立語意層

目標:知道每個東西為什麼存在。

任務:

- 為核心檔案補摘要
- 為核心流程建立 flow map
- 為 domain concept 建立 glossary
- 為重要 API 建立用途說明

完成標準:

工程師可以用業務語言搜尋 code,例如「登入流程」、「付款驗證」、「搜尋排序」。

Phase 3:建立架構規則

目標:讓架構可以被檢查。

任務:

- 定義 layer
- 定義允許與禁止的 dependency
- 檢查 circular dependency
- 檢查 cross-layer violation
- 建立 architecture-rules.md

完成標準:

每個 PR 都能知道是否破壞架構邊界。

Phase 4:建立命名與可讀性規範

目標:讓 code 自己說明自己。

任務:

- 建立 naming-rules.md
- 清理模糊名稱
- 拆分過大的 utils / service / manager
- 為核心 domain 建立一致術語

完成標準:

相同概念在整個專案中使用相同名稱。

Phase 5:整合進日常維護

目標:讓知識圖譜持續更新。

任務:

- PR 前跑 change impact analysis
- release 前更新 architecture map
- onboarding 使用 guided tour
- refactor 前先看 dependency risk
- 定期檢查 dead code 與 circular dependency

完成標準:

架構文件不再是一次性文件,而是跟著 codebase 一起演進。

6. 對團隊的落地建議

小型專案

先做:

- 檔案與 dependency map
- 核心流程說明
- 命名規範
- PR checklist

不要一開始就過度設計。


中型專案

加入:

- layer 標註
- domain map
- change impact report
- onboarding guide
- high-risk module list

大型專案

必須加入:

- 自動化 architecture check
- CI dependency report
- ownership map
- service boundary map
- deprecated module tracking
- architecture decision records

7. 最重要的設計原則

原則 1:可理解性是架構品質的一部分

如果一個系統只能由原作者理解,那它不是好系統。


原則 2:命名是最低成本的文件

好的命名可以減少文件需求。
壞的命名會讓再多文件都救不回來。


原則 3:依存關係比資料夾結構更真實

資料夾看起來乾淨,不代表架構乾淨。
真正的架構藏在 import、call、data flow、event flow 裡。


原則 4:AI 應該輔助建立地圖,而不是盲目修改 code

先理解,再修改。
先看結構,再看細節。
先問影響,再動手。


原則 5:文件應該從 code 生成,再由人校正

純手寫文件容易過期。
從 code graph 產生的文件較接近現況。
人類負責補上意圖、取捨、背景與設計理由。


8. 最終目標

把 Understand-Anything 這類工具的能力整合進專案,不是為了「看起來很 AI」,而是為了建立一種新的工程習慣:

寫 code 的同時,也讓 codebase 更容易被理解。

最終專案應該做到:

新人能快速 onboarding
AI 能準確讀懂上下文
工程師能看見依存風險
Reviewer 能檢查架構邊界
PM / QA / Security 能理解核心流程
重構有客觀優先順序
命名與 domain 語言一致
文件能隨 code 演進

一句話總結:

好的專案不只是能執行,而是能被理解、被導航、被審查、被安全地修改。

這份說明的根基來自 Understand-Anything 的設計:它用 multi-agent pipeline 建立 codebase knowledge graph,並支援 /understand/understand-dashboard/understand-chat/understand-diff/understand-explain/understand-onboard 等工作流;其網站也強調不只是顯示節點與線,而是把程式結構映射到 business logic、flows、guided tours 與 dependency path。(GitHub)

沒有留言:

張貼留言