Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 16 — Use case writing theo template Cockburn

Từ Designer sang BA: Lộ Trình Chuyển Đổi Bài 16/60

Mở đầu — vì sao bài này quan trọng

Nếu bạn đến từ nền Design, có thể bạn đã quen với việc vẽ user flow, prototype hoặc viết vài dòng mô tả tính năng trong Figma. Nhưng khi bước vào vai trò BA, bạn sẽ nhanh chóng nhận ra một sự thật: dev không đọc prototype của bạn để hiểu "chuyện gì xảy ra khi user bấm nút mà tài khoản đã bị khóa". Họ cần một tài liệu mô tả hành vi của hệ thống theo từng bước, kèm mọi nhánh rẽ. Đó chính là lúc use case lên tiếng.

Use case là một trong những công cụ nền tảng nhất của BA để đặc tả yêu cầu chức năng. Và trong tất cả các cách viết use case, template Cockburn (do Alistair Cockburn — một trong 17 người ký Tuyên ngôn Agile — đề xuất) là chuẩn được dạy nhiều nhất, được dùng nhiều nhất trong thực tế doanh nghiệp Việt Nam, đặc biệt tại các công ty outsourcing, fintech và ngân hàng.

Lý do bài này quan trọng với người chuyển từ Design: use case buộc bạn chuyển từ tư duy "màn hình đẹp, luồng mượt" sang tư duy "hệ thống phải xử lý đủ mọi tình huống — kể cả những tình huống xấu mà designer thường bỏ qua vì nó không nằm trên happy path". Một designer nghĩ về 1 luồng chính; một BA giỏi nghĩ về 1 luồng chính và 8 luồng ngoại lệ. Bài này dạy bạn cách viết ra đủ cả 9 luồng đó một cách có kỷ luật.

Khái niệm cốt lõi

Use case là gì

Use case mô tả một chuỗi tương tác giữa actor (người dùng hoặc hệ thống bên ngoài) và hệ thống nhằm đạt được một mục tiêu cụ thể. Điểm mấu chốt: use case luôn xoay quanh một mục tiêu (goal), không phải quanh một màn hình. "Đặt hàng thành công" là một goal. "Màn hình giỏ hàng" không phải là một use case.

Đây là điểm khác biệt tư duy đầu tiên so với Design: designer tổ chức công việc theo màn hình/screen, BA tổ chức theo mục tiêu nghiệp vụ.

Cấu trúc đầy đủ của template Cockburn

Một use case theo Cockburn bao gồm các thành phần sau:

Use Case: <Động từ + Danh từ, ví dụ "Rút tiền tại ATM">
Scope (Phạm vi): <Hệ thống nào chịu trách nhiệm>
Level (Cấp độ): <User-goal / Subfunction / Summary>
Primary Actor (Tác nhân chính): <Ai khởi tạo use case>
Stakeholders & Interests (Bên liên quan & lợi ích): <Ai quan tâm điều gì>
Preconditions (Điều kiện tiên quyết): <Điều gì đúng TRƯỚC khi bắt đầu>
Success Guarantee / Postconditions: <Điều gì đúng SAU khi thành công>
Minimal Guarantee: <Điều tối thiểu hệ thống đảm bảo dù thất bại>
Trigger (Kích hoạt): <Sự kiện khởi động use case>
Main Success Scenario (Luồng chính): <Các bước đánh số, đường happy path>
Extensions (Luồng mở rộng/ngoại lệ): <Các nhánh rẽ, lỗi, điều kiện khác>

Hãy đi qua từng phần với con mắt của người từng làm Design.

Đặt tên use case

Luôn dùng công thức động từ chủ động + danh từ (đối tượng): "Thanh toán đơn hàng", "Đặt lại mật khẩu", "Duyệt hồ sơ vay". Đừng đặt tên kiểu danh từ trơ như "Quản lý người dùng" — đó là một mớ chức năng, không phải một use case đơn.

Level — cấp độ của use case

Cockburn mô tả cấp độ bằng ẩn dụ độ cao mặt biển:

  • User-goal (mặt biển, ký hiệu ~biểu tượng con cá/sea-level): mục tiêu một người dùng hoàn thành trong một lần ngồi làm việc. Đây là cấp độ bạn sẽ viết 90% thời gian. Ví dụ: "Đặt vé xe khách".
  • Summary (trên mây, ký hiệu cánh diều/cloud): gộp nhiều user-goal, mô tả bối cảnh rộng. Ví dụ: "Hoàn tất quy trình vay tiêu dùng".
  • Subfunction (dưới đáy biển, ký hiệu con sò/clam): bước nhỏ được nhiều use case dùng lại. Ví dụ: "Xác thực OTP".

Stakeholders & Interests — phần mà designer hay bỏ sót

Đây là phần cực kỳ giá trị và cũng là chỗ tư duy empathy của designer phát huy tác dụng. Bạn liệt kê mọi bên liên quan cùng lợi ích họ muốn được bảo vệ. Ví dụ với "Rút tiền ATM": khách hàng muốn lấy đúng số tiền; ngân hàng muốn không mất tiền và ghi nợ chính xác; cơ quan kiểm toán muốn mọi giao dịch có log. Chính danh sách lợi ích này sẽ sinh ra các bước trong luồng chính và các nhánh ngoại lệ. Đây là "empathy map" phiên bản nghiệp vụ.

Main Success Scenario và Extensions

Luồng chính là con đường lý tưởng: không lỗi, không nhánh rẽ, mọi thứ suôn sẻ, đánh số 1, 2, 3... Extensions là nơi bạn xử lý mọi thứ có thể sai. Mỗi extension gắn với số bước trong luồng chính: ví dụ bước 3 của luồng chính là "Hệ thống kiểm tra số dư", thì extension "3a. Số dư không đủ" mô tả điều gì xảy ra. Chính phần Extensions này là nơi phân biệt một BA nghiệp dư với một BA giỏi.

Tình huống thực tế

Ví dụ 1: Rút tiền tại ATM (case kinh điển của Cockburn)

Đây là ví dụ gốc mà Cockburn dùng để dạy. Tôi viết lại theo bối cảnh một ngân hàng Việt Nam giả định — "Ngân hàng SaigonPay".

Use Case: Rút tiền mặt tại ATM
Scope: Hệ thống ATM của SaigonPay
Level: User-goal
Primary Actor: Chủ thẻ (Cardholder)
Stakeholders & Interests:
  - Chủ thẻ: nhận đúng số tiền yêu cầu, thẻ được trả lại.
  - SaigonPay: chỉ chi tiền khi số dư đủ, ghi nợ chính xác, có log giao dịch.
Preconditions: Máy ATM đang hoạt động, còn tiền mặt; thẻ hợp lệ đã cắm.
Success Guarantee: Tài khoản bị ghi nợ đúng số tiền; tiền đã được đưa ra.
Minimal Guarantee: Nếu lỗi, tài khoản KHÔNG bị ghi nợ; giao dịch được log.
Trigger: Chủ thẻ chọn "Rút tiền".

Main Success Scenario: 1. Chủ thẻ nhập số tiền muốn rút. 2. Hệ thống xác nhận số tiền hợp lệ (bội số 50.000đ). 3. Hệ thống kiểm tra số dư đủ. 4. Hệ thống ghi nợ tài khoản. 5. Hệ thống nhả tiền và in biên lai. 6. Hệ thống trả thẻ.

Extensions: 2a. Số tiền không phải bội số 50.000đ: 2a1. Hệ thống báo lỗi, yêu cầu nhập lại. 3a. Số dư không đủ: 3a1. Hệ thống thông báo và quay lại bước 1. 4a. Kết nối tới core banking bị gián đoạn: 4a1. Hệ thống hủy giao dịch, KHÔNG nhả tiền, trả thẻ, ghi log lỗi. 5a. Khay tiền kẹt: 5a1. Hệ thống hoàn tác ghi nợ (reversal), ghi log, báo nhân viên kỹ thuật.

Bài học rút ra: Luồng chính chỉ có 6 bước, nhưng phần thực sự bảo vệ khách hàng và ngân hàng nằm ở Extensions — đặc biệt 4a và 5a (đã nhả tiền chưa, đã ghi nợ chưa). Một designer thường chỉ vẽ tới bước "nhả tiền thành công". Một BA phải trả lời câu hỏi: "Nếu ghi nợ xong mà máy kẹt tiền thì sao?" Câu trả lời (reversal) chính là thứ giúp ngân hàng tránh khiếu nại và mất tiền.

Ví dụ 2: Đặt món trên app giao đồ ăn (bối cảnh startup VN)

Giả sử bạn là BA tại một startup giao đồ ăn tên "ShipNgon", vừa chuyển từ vị trí Product Designer sang. PM giao bạn đặc tả tính năng "áp mã giảm giá khi thanh toán".

Use Case: Áp mã giảm giá vào đơn hàng
Scope: App ShipNgon (mobile)
Level: Subfunction (được dùng lại trong nhiều luồng thanh toán)
Primary Actor: Khách hàng
Stakeholders & Interests:
  - Khách hàng: được giảm đúng số tiền, thấy giá cuối rõ ràng.
  - ShipNgon: mã chỉ áp dụng đúng điều kiện, không bị lạm dụng.
  - Nhà hàng: doanh thu thực nhận không bị ảnh hưởng bởi khuyến mãi của sàn.
Preconditions: Khách đã có ít nhất 1 món trong giỏ, đã đăng nhập.
Success Guarantee: Giá cuối được cập nhật đúng; mã được đánh dấu "đã dùng".
Minimal Guarantee: Nếu mã không hợp lệ, giá gốc giữ nguyên, không trừ lượt dùng.
Trigger: Khách nhập mã và bấm "Áp dụng".

Main Success Scenario: 1. Khách nhập mã giảm giá. 2. Hệ thống kiểm tra mã tồn tại và còn hiệu lực. 3. Hệ thống kiểm tra đơn thỏa điều kiện (giá trị tối thiểu 50.000đ). 4. Hệ thống tính lại tổng tiền và hiển thị số tiền được giảm.

Extensions: 2a. Mã không tồn tại / đã hết hạn: 2a1. Hệ thống báo "Mã không hợp lệ", giữ nguyên giá. 2b. Mã đã dùng hết lượt toàn hệ thống: 2b1. Hệ thống báo "Mã đã hết lượt". 3a. Đơn chưa đạt giá trị tối thiểu: 3a1. Hệ thống báo "Đơn tối thiểu 50.000đ để dùng mã này". 3b. Khách đã dùng mã này trước đó (giới hạn 1 lần/khách): 3b1. Hệ thống báo "Bạn đã sử dụng mã này rồi". 4a. Sau khi áp mã, khách xóa món khiến đơn dưới mức tối thiểu: 4a1. Hệ thống tự gỡ mã và thông báo.

Bài học rút ra: Chú ý extension 4a — đây là một tình huống động (dynamic) mà nếu chỉ nghĩ theo luồng tuyến tính bạn sẽ bỏ sót. Nghiệp vụ khuyến mãi có vô số cách "lách", và mỗi cách lách là một extension. Chính việc bạn liệt kê được 3b (một khách dùng nhiều lần) và 2b (mã hết lượt toàn hệ thống) là hai điều kiện khác nhau — sẽ giúp dev thiết kế đúng ràng buộc ở database. Nếu bạn viết chung chung "mã không hợp lệ", dev sẽ code thiếu.

Ví dụ 3: Duyệt hồ sơ vay tại công ty tài chính tiêu dùng

Bối cảnh: bạn làm BA tại một công ty tài chính tiêu dùng giống FE Credit, đặc tả use case cho nhân viên thẩm định.

Ở đây Primary Actor không phải khách hàng cuối mà là Chuyên viên thẩm định. Điểm đáng chú ý là use case này ở Level Summary vì nó gộp nhiều bước con: xác thực CMND/CCCD, chấm điểm tín dụng (credit scoring), kiểm tra CIC.

Use Case: Duyệt hồ sơ vay tiêu dùng
Level: Summary
Primary Actor: Chuyên viên thẩm định
Stakeholders & Interests:
  - Công ty: giảm rủi ro nợ xấu, tuân thủ quy định Ngân hàng Nhà nước.
  - Khách hàng: được phản hồi trong 24h.
Main Success Scenario:
  1. Hệ thống hiển thị hồ sơ mới cần thẩm định.
  2. Chuyên viên xác minh giấy tờ tùy thân. (<< Xác thực CCCD >>)
  3. Hệ thống truy vấn điểm tín dụng CIC. (<< Kiểm tra CIC >>)
  4. Chuyên viên ra quyết định: duyệt / từ chối / yêu cầu bổ sung.

Extensions: 3a. CIC trả về nợ xấu nhóm 3 trở lên: 3a1. Hệ thống gợi ý từ chối, chuyển hồ sơ sang cấp quản lý duyệt. 4a. Chuyên viên yêu cầu bổ sung hồ sơ: 4a1. Hệ thống gửi SMS cho khách, đặt trạng thái "Chờ bổ sung".

Bài học rút ra: Ký hiệu << ... >> cho biết bước đó gọi tới một use case con (subfunction) — giúp bạn tránh viết lại logic xác thực CCCD trong 10 use case khác nhau. Đây là cách Cockburn xử lý reuse, tương tự tư duy component reuse trong design system mà bạn đã quen.

Hướng dẫn từng bước

Đây là quy trình 7 bước để viết một use case Cockburn từ đầu:

  • Xác định Primary Actor và goal. Hỏi: "Ai muốn làm gì?" Đặt tên theo công thức động từ + danh từ.
  • Chọn Level. Đây có phải mục tiêu hoàn thành trong một lần ngồi (user-goal), hay là bước con dùng lại (subfunction), hay là bối cảnh rộng (summary)?
  • Liệt kê Stakeholders & Interests. Đây là bước quan trọng nhất và cũng là nơi bạn dùng lợi thế empathy. Mỗi lợi ích bạn ghi ra sẽ trở thành một điều luồng chính hoặc extension phải bảo vệ.
  • Viết Preconditions và Postconditions. Precondition = điều đã đúng trước khi bắt đầu (không kiểm tra lại trong luồng). Success Guarantee = trạng thái sau khi thành công. Minimal Guarantee = điều tối thiểu đảm bảo ngay cả khi thất bại (thường bị bỏ quên, nhưng cực quan trọng với hệ thống tiền bạc).
  • Viết Main Success Scenario. Chỉ viết happy path, 3–9 bước là lý tưởng. Mỗi bước là một câu chủ động: "Ai làm gì". Xen kẽ actor và system. Đừng nhồi lỗi vào đây.
  • Rà từng bước để sinh Extensions. Với mỗi bước, hỏi: "Bước này có thể sai theo cách nào?" Đánh số theo bước (3a, 3b, 4a...). Đây là phần chiếm nhiều công sức nhất và tạo ra nhiều giá trị nhất.
  • Review chéo với dev và stakeholder. Đọc to luồng chính cho PM/dev nghe. Nếu có ai hỏi "thế nếu..." mà bạn chưa có extension, bạn vừa tìm ra một lỗ hổng.

Lỗi thường gặp & mẹo

Lỗi 1 — Viết use case như mô tả UI. Sai: "Khách bấm nút xanh ở góc phải để mở popup." Đúng: "Khách yêu cầu áp mã giảm giá." Use case mô tả ý định và hành vi hệ thống, không mô tả pixel. Đây là cạm bẫy số một của người từ Design. Giữ use case độc lập với giao diện để khi UI đổi, use case vẫn đúng.

Lỗi 2 — Nhồi điều kiện IF/ELSE vào luồng chính. Sai: "Nếu số dư đủ thì..., ngược lại thì...". Luồng chính chỉ có một con đường thẳng; mọi rẽ nhánh thuộc về Extensions. Nếu luồng chính của bạn có chữ "nếu", hãy tách nó ra.

Lỗi 3 — Quên Minimal Guarantee. Với hệ thống thanh toán, ngân hàng, đây là dòng bảo vệ bạn khỏi việc "khách bị trừ tiền mà không nhận hàng". Luôn tự hỏi: "Nếu mọi thứ sập giữa chừng, hệ thống tối thiểu đảm bảo điều gì?"

Lỗi 4 — Level lẫn lộn. Trộn một summary với các bước chi tiết cấp subfunction trong cùng một use case khiến tài liệu dài lê thê. Tách ra theo cấp độ, dùng ký hiệu << >> để gọi use case con.

Lỗi 5 — Extensions viết mơ hồ. "Xử lý lỗi" là vô nghĩa với dev. Phải cụ thể: lỗi gì, hệ thống làm gì, quay về đâu, trạng thái ra sao.

Mẹo: Số bước luồng chính lý tưởng là 3–9. Nếu quá 9 bước, use case của bạn có lẽ đang ở nhầm cấp độ và nên tách. Nếu chỉ 1–2 bước, có lẽ nó chỉ là subfunction.

Mẹo: Đọc luồng chính như một câu chuyện. Nếu nghe không mượt như kể chuyện, nó chưa đúng.

Bài tập thực hành

Bài tập 1 (cơ bản): Viết use case đầy đủ theo template Cockburn cho chức năng "Đặt lại mật khẩu qua email". Yêu cầu: ít nhất 4 bước luồng chính và tối thiểu 4 extensions (ví dụ: email không tồn tại, link hết hạn, mật khẩu mới trùng mật khẩu cũ, nhập sai xác nhận mật khẩu).

Bài tập 2 (nâng cao — bối cảnh VN): Bạn là BA cho một ví điện tử như MoMo. Viết use case "Chuyển tiền cho người khác qua số điện thoại". Bắt buộc có: đầy đủ Stakeholders & Interests (khách gửi, khách nhận, ví điện tử, cơ quan quản lý), Minimal Guarantee, và ít nhất 6 extensions bao gồm: số điện thoại không có tài khoản ví, số dư không đủ, vượt hạn mức ngày, nhập sai OTP quá 3 lần, hệ thống mất kết nối sau khi đã trừ tiền người gửi.

Bài tập 3 (chuyển đổi tư duy): Lấy một prototype/user flow bạn từng làm thời Design. Chuyển nó thành một use case Cockburn hoàn chỉnh. Sau đó tự đếm: prototype cũ của bạn đã bỏ sót bao nhiêu extension? Con số này chính là thước đo khoảng cách giữa tư duy Design và tư duy BA của bạn.

Tóm tắt

Use case theo template Cockburn là công cụ để BA đặc tả hành vi hệ thống một cách có kỷ luật, xoay quanh mục tiêu chứ không phải màn hình. Cấu trúc cốt lõi gồm: tên (động từ + danh từ), Level, Primary Actor, Stakeholders & Interests, Preconditions, các Guarantee, Trigger, Main Success Scenario và Extensions.

Ba điều quan trọng nhất cần nhớ khi chuyển từ Design sang BA: (1) tổ chức theo goal, không theo UI; (2) luồng chính chỉ là happy path — giá trị thật nằm ở Extensions, nơi bạn xử lý mọi tình huống xấu mà designer thường bỏ qua; (3) Stakeholders & Interests là "empathy map nghiệp vụ" — dùng lợi thế thấu cảm của bạn để sinh ra các bước và ràng buộc mà hệ thống phải bảo vệ.

Kỹ năng viết use case sẽ là nền tảng cho các bài tiếp theo: user story và acceptance criteria (Bài 17) sẽ bổ sung góc nhìn Agile, còn wireframe annotation (Bài 24) sẽ cho thấy design artifact và use case bổ trợ nhau thế nào. Hãy luyện tập cho tới khi việc nghĩ ra 8 extension trở thành phản xạ tự nhiên — đó là lúc bạn thật sự tư duy như một BA.