Diagramming(圖表繪製)
概覽
使用 Mermaid 語法建立清晰、易於維護的技術圖表。此技能涵蓋架構圖、循序圖、實體關係圖、流程圖和狀態圖,用於記錄軟體系統。
操作說明
1. 選擇正確的圖表類型
| 圖表類型 | 適用時機 |
|---|---|
| 架構/C4 | 顯示系統結構與元件 |
| 循序圖 | 顯示隨時間變化的互動 |
| ERD | 顯示資料模型與關係 |
| 流程圖 | 顯示決策邏輯與流程 |
| 狀態圖 | 顯示狀態轉換 |
2. 一般 Mermaid 原則
- 保持圖表聚焦於單一概念
- 使用一致的命名慣例
- 為關係加上描述性標籤
- 限制複雜度(分割大型圖表)
- 使用註解進行文件說明
最佳實踐
- 簡潔:一張圖表,一個概念
- 一致性:相關圖表間使用相同命名
- 可讀性:從左到右或從上到下的流程
- 標籤:務必標示關係與轉換
- 脈絡:包含標題與簡短描述
範例
架構圖(C4 模型)
脈絡圖(第 1 層)
C4Context
title System Context Diagram for E-Commerce Platform
Person(customer, "Customer", "A user who purchases products")
Person(admin, "Admin", "Manages products and orders")
System(ecommerce, "E-Commerce Platform", "Allows customers to browse and purchase products")
System_Ext(payment, "Payment Gateway", "Handles payment processing")
System_Ext(shipping, "Shipping Provider", "Handles order fulfillment")
System_Ext(email, "Email Service", "Sends notifications")
Rel(customer, ecommerce, "Browses, purchases")
Rel(admin, ecommerce, "Manages")
Rel(ecommerce, payment, "Processes payments")
Rel(ecommerce, shipping, "Creates shipments")
Rel(ecommerce, email, "Sends emails")
容器圖(第 2 層)
C4Container
title Container Diagram for E-Commerce Platform
Person(customer, "Customer")
Container_Boundary(ecommerce, "E-Commerce Platform") {
Container(web, "Web Application", "React", "Customer-facing UI")
Container(api, "API Gateway", "Node.js", "REST API")
Container(cart, "Cart Service", "Node.js", "Shopping cart management")
Container(catalog, "Catalog Service", "Python", "Product catalog")
Container(order, "Order Service", "Java", "Order processing")
ContainerDb(db, "Database", "PostgreSQL", "Stores all data")
ContainerQueue(queue, "Message Queue", "RabbitMQ", "Async messaging")
}
Rel(customer, web, "Uses", "HTTPS")
Rel(web, api, "Calls", "JSON/HTTPS")
Rel(api, cart, "Routes to")
Rel(api, catalog, "Routes to")
Rel(api, order, "Routes to")
Rel(cart, db, "Reads/writes")
Rel(catalog, db, "Reads")
Rel(order, db, "Reads/writes")
Rel(order, queue, "Publishes events")
元件圖(第 3 層)
flowchart TB
subgraph "Order Service"
controller[Order Controller]
service[Order Service]
repo[Order Repository]
validator[Order Validator]
publisher[Event Publisher]
end
subgraph "External"
db[(PostgreSQL)]
queue[RabbitMQ]
end
controller --> service
service --> validator
service --> repo
service --> publisher
repo --> db
publisher --> queue
循序圖
基本請求流程
sequenceDiagram
autonumber
participant C as Client
participant G as API Gateway
participant A as Auth Service
participant S as Service
participant D as Database
C->>G: POST /api/resource
G->>A: Validate token
A-->>G: Token valid
G->>S: Forward request
S->>D: Query data
D-->>S: Return results
S-->>G: Response (200 OK)
G-->>C: Response with data
錯誤處理流程
sequenceDiagram
participant C as Client
participant S as Service
participant D as Database
C->>S: POST /api/users
S->>S: Validate input
alt Validation fails
S-->>C: 400 Bad Request
else Validation passes
S->>D: INSERT user
alt Database error
D-->>S: Constraint violation
S-->>C: 409 Conflict
else Success
D-->>S: User created
S-->>C: 201 Created
end
end
非同步處理
sequenceDiagram
participant C as Client
participant API as API
participant Q as Queue
participant W as Worker
participant N as Notification
C->>API: Submit job
API->>Q: Enqueue job
API-->>C: 202 Accepted (job ID)
Note over Q,W: Async processing
Q->>W: Dequeue job
W->>W: Process job
W->>N: Send notification
N-->>C: Job complete notification
實體關係圖
基本 ERD
erDiagram
USER ||--o{ ORDER : places
USER {
uuid id PK
string email UK
string name
timestamp created_at
}
ORDER ||--|{ ORDER_ITEM : contains
ORDER {
uuid id PK
uuid user_id FK
decimal total
string status
timestamp created_at
}
ORDER_ITEM }|--|| PRODUCT : references
ORDER_ITEM {
uuid id PK
uuid order_id FK
uuid product_id FK
int quantity
decimal price
}
PRODUCT ||--o{ PRODUCT_CATEGORY : "belongs to"
PRODUCT {
uuid id PK
string name
text description
decimal price
int stock
}
CATEGORY ||--o{ PRODUCT_CATEGORY : contains
CATEGORY {
uuid id PK
string name
uuid parent_id FK
}
PRODUCT_CATEGORY {
uuid product_id PK,FK
uuid category_id PK,FK
}
附關係說明的 ERD
erDiagram
CUSTOMER ||--o{ ORDER : "places (1:N)"
ORDER ||--|{ LINE_ITEM : "contains (1:N, required)"
PRODUCT ||--o{ LINE_ITEM : "appears in (1:N)"
CUSTOMER }|--|| ADDRESS : "has billing (N:1, required)"
CUSTOMER }o--o{ ADDRESS : "has shipping (N:N)"
關係標記:
||恰好一個o|零或一個}|一個或多個}o零或多個
流程圖
決策邏輯
flowchart TD
A[Start: User Login] --> B{Valid credentials?}
B -->|Yes| C{2FA enabled?}
B -->|No| D[Show error message]
D --> A
C -->|Yes| E[Send 2FA code]
E --> F{Code valid?}
F -->|Yes| G[Create session]
F -->|No| H{Attempts < 3?}
H -->|Yes| E
H -->|No| I[Lock account]
C -->|No| G
G --> J[Redirect to dashboard]
J --> K[End]
I --> K
流程處理
flowchart LR
subgraph "CI Pipeline"
A[Push Code] --> B[Run Tests]
B --> C{Tests Pass?}
C -->|Yes| D[Build Image]
C -->|No| E[Notify Developer]
D --> F[Push to Registry]
end
subgraph "CD Pipeline"
F --> G[Deploy to Staging]
G --> H[Run E2E Tests]
H --> I{Tests Pass?}
I -->|Yes| J[Deploy to Production]
I -->|No| K[Rollback]
end
狀態圖
訂單狀態機
stateDiagram-v2
[*] --> Draft: Create order
Draft --> Pending: Submit
Draft --> Cancelled: Cancel
Pending --> Confirmed: Payment received
Pending --> Cancelled: Payment failed
Pending --> Cancelled: Timeout (24h)
Confirmed --> Processing: Begin fulfillment
Confirmed --> Cancelled: Customer cancel
Processing --> Shipped: Ship order
Processing --> Cancelled: Out of stock
Shipped --> Delivered: Delivery confirmed
Shipped --> Returned: Return initiated
Delivered --> Returned: Return requested
Delivered --> [*]: Complete
Returned --> Refunded: Process refund
Refunded --> [*]: Complete
Cancelled --> [*]: Complete
連線狀態機
stateDiagram-v2
[*] --> Disconnected
Disconnected --> Connecting: connect()
Connecting --> Connected: success
Connecting --> Disconnected: failure
Connected --> Disconnected: disconnect()
Connected --> Reconnecting: connection lost
Reconnecting --> Connected: success
Reconnecting --> Disconnected: max retries
note right of Reconnecting
Exponential backoff
Max 5 retries
end note
類別圖
classDiagram
class Repository~T~ {
<<interface>>
+findById(id: string) T
+findAll() List~T~
+save(entity: T) T
+delete(id: string) void
}
class UserRepository {
-db: Database
+findById(id: string) User
+findAll() List~User~
+save(entity: User) User
+delete(id: string) void
+findByEmail(email: string) User
}
class User {
+id: string
+email: string
+name: string
+createdAt: Date
+validate() boolean
}
Repository~T~ <|.. UserRepository
UserRepository --> User