Mở đầu — vì sao bài này quan trọng
Khi còn là developer, bạn từng "ăn đủ" những đêm trắng vì một lý do rất quen thuộc: hệ thống chạy đúng chức năng nhưng vẫn sập. Tính năng đặt hàng vẫn hoạt động — chỉ có điều khi 5.000 người vào cùng lúc thì trang treo cứng. Form đăng nhập vẫn đúng logic — chỉ có điều mất 8 giây mới phản hồi. Báo cáo vẫn xuất ra — chỉ có điều dữ liệu khách hàng bị lộ vì không mã hóa.
Tất cả những "chỉ có điều" đó chính là Non-Functional Requirements (NFR) — yêu cầu phi chức năng. Và đây là vùng đất mà bạn, người từng làm dev, có lợi thế khổng lồ so với BA xuất thân kinh doanh. Vì bạn đã từng trả giá cho việc NFR bị bỏ quên.
Vấn đề là: phần lớn BA viết requirements rất giỏi mô tả hệ thống làm gì (functional), nhưng cực kỳ lúng túng khi phải đặc tả hệ thống làm tốt đến mức nào (non-functional). Họ viết "hệ thống phải nhanh", "hệ thống phải bảo mật" — những câu vô nghĩa với đội dev vì không thể test, không thể nghiệm thu, không thể tranh luận. Bài này dạy bạn biến những mong muốn mơ hồ đó thành NFR đo lường được, có thể kiểm thử và bảo vệ được trước stakeholder. Đây là bài đào sâu, nên ta sẽ đi tới tận con số.
Khái niệm cốt lõi
NFR là gì và khác Functional Requirement ra sao
Functional Requirement (FR) trả lời câu hỏi "Hệ thống làm gì?" — ví dụ: "Người dùng có thể chuyển tiền giữa hai tài khoản." NFR trả lời câu hỏi "Hệ thống vận hành với chất lượng ra sao?" — ví dụ: "Giao dịch chuyển tiền phải hoàn tất trong 2 giây với 95% trường hợp, ngay cả khi có 3.000 giao dịch đồng thời."
NFR không mô tả một hành vi mới, mà là ràng buộc chất lượng (quality attributes) áp lên các hành vi đã có. Đó là lý do người ta hay gọi chúng là "-ilities": reliability, scalability, usability, maintainability, security... Một hệ thống có thể đúng 100% functional nhưng vẫn thất bại hoàn toàn vì NFR.
Khung FURPS+ — bản đồ 7 nhóm NFR
Có nhiều cách phân loại NFR (ISO 25010, FURPS+...), nhưng với dev chuyển BA, mình khuyên dùng FURPS+ của HP/IBM vì nó dễ nhớ và bao quát. Tên gọi đến từ chữ cái đầu của các nhóm:
1. Functionality (Chức năng — phần mở rộng): Nhóm này phần lớn chồng lấn với FR, nhưng có những khía cạnh "chất lượng của chức năng" thuộc về NFR — đặc biệt là security (bảo mật) và auditability (khả năng truy vết). Ví dụ: phân quyền, mã hóa, ghi log audit trail. Đây là lý do FURPS đặt security vào đây thay vì tách riêng.
2. Usability (Khả năng sử dụng): Hệ thống dễ dùng đến mức nào? Bao gồm tính dễ học (learnability), tính nhất quán giao diện, khả năng tiếp cận (accessibility — ví dụ tuân thủ WCAG 2.1 AA cho người khiếm thị), số bước để hoàn thành tác vụ, chất lượng thông báo lỗi. Đo bằng: thời gian onboarding, tỷ lệ hoàn thành tác vụ, số click.
3. Reliability (Độ tin cậy): Hệ thống chạy ổn định đến mức nào? Gồm uptime/availability (ví dụ 99,9% — tương đương downtime tối đa 43 phút/tháng), MTBF (Mean Time Between Failures), MTTR (Mean Time To Recovery), khả năng chịu lỗi (fault tolerance), khả năng khôi phục dữ liệu (recoverability — RPO/RTO).
4. Performance (Hiệu năng): Hệ thống nhanh và "khỏe" đến mức nào? Gồm response time (thời gian phản hồi), throughput (số giao dịch/giây — TPS), latency, capacity (số người dùng đồng thời), và resource utilization (CPU, RAM). Đây là nhóm dev quen thuộc nhất.
5. Supportability (Khả năng hỗ trợ/bảo trì): Hệ thống dễ vận hành, bảo trì, mở rộng đến mức nào? Gồm maintainability, testability, configurability, khả năng giám sát (monitoring/observability), khả năng cài đặt và triển khai, tính tương thích (compatibility với trình duyệt, OS, thiết bị).
Dấu "+" trong FURPS+ gom các ràng buộc không nằm gọn trong 5 nhóm trên:
- Design constraints: bắt buộc dùng công nghệ nào (ví dụ phải dùng Oracle DB vì doanh nghiệp đã mua license).
- Implementation constraints: chuẩn coding, ngôn ngữ.
- Interface constraints: phải tích hợp với hệ thống cũ qua giao thức nào.
- Physical constraints: phần cứng, on-premise hay cloud.
- Legal/Compliance: tuân thủ pháp lý — Nghị định 13/2023 về bảo vệ dữ liệu cá nhân tại Việt Nam, PCI-DSS cho thanh toán thẻ, GDPR nếu phục vụ khách EU.
Đặc điểm của một NFR tốt: SMART và testable
Một NFR phải đo lường được. Nguyên tắc vàng: mỗi NFR phải gắn với một con số và một điều kiện. Cấu trúc kinh điển:
> "[Thành phần] phải [đặc tính chất lượng] đạt [giá trị đo] dưới [điều kiện cụ thể], đo bằng [phương pháp]."
So sánh:
- Sai: "Hệ thống phải nhanh."
- Đúng: "Trang danh sách sản phẩm phải tải xong (Largest Contentful Paint) dưới 2,5 giây ở phân vị thứ 95 (p95), với 2.000 người dùng đồng thời, đo qua công cụ k6 trên môi trường staging."
Tình huống thực tế
Tình huống 1 — Sàn TMĐT VN sập trong campaign 12.12
Một sàn thương mại điện tử tại TP.HCM (giả định, quy mô tương đương Tiki/Sendo) chuẩn bị cho đợt sale 12.12. BA — vốn xuất thân kinh doanh — viết requirement: "Hệ thống phải xử lý được lượng truy cập lớn trong ngày sale." Đội dev gật đầu, không ai phản đối vì câu đó... không có gì để phản đối.
Kết quả: 20h ngày 12.12, lượng truy cập đạt đỉnh, trang chủ mất 14 giây để tải, giỏ hàng báo lỗi 503. Trong 40 phút sập, ước tính mất khoảng 2,8 tỷ đồng doanh thu và vô số khách rời bỏ.
Khi một BA-từng-là-dev tham gia mổ xẻ, anh viết lại NFR như sau:
- Capacity: Hệ thống phải phục vụ 50.000 người dùng đồng thời (DAU đỉnh dự kiến gấp 8 lần ngày thường là 6.200).
- Throughput: Tối thiểu 1.500 đơn hàng/phút ở giờ cao điểm.
- Performance: Trang sản phẩm tải dưới 3s ở p95; API thêm-vào-giỏ phản hồi dưới 500ms ở p99.
- Reliability: Uptime 99,95% trong khung giờ sale (20h–24h), tự động scale khi CPU > 70%.
- Graceful degradation: Khi quá tải, vẫn cho phép xem sản phẩm dù tạm khóa tính năng gợi ý.
Tình huống 2 — Ứng dụng ngân hàng số và yêu cầu bảo mật mơ hồ
Một ngân hàng số (neobank) ở Việt Nam phát triển app eKYC. BA viết: "Dữ liệu khách hàng phải được bảo mật." Câu này nghe có vẻ đầy đủ, nhưng khi đội security audit vào, họ hỏi: Mã hóa ở tầng nào? Khi truyền hay khi lưu? Thuật toán gì? Audit log giữ bao lâu?
NFR được viết lại theo nhóm Functionality (security) của FURPS+ và phần Compliance:
- Encryption in transit: Toàn bộ kết nối dùng TLS 1.3, không chấp nhận downgrade.
- Encryption at rest: Dữ liệu định danh (CCCD, ảnh khuôn mặt) mã hóa AES-256.
- Authentication: Bắt buộc 2FA cho mọi giao dịch trên 10 triệu đồng (phù hợp Quyết định 2345 của NHNN về xác thực sinh trắc học).
- Auditability: Mọi truy cập dữ liệu cá nhân ghi log bất biến, lưu tối thiểu 12 tháng.
- Compliance: Tuân thủ Nghị định 13/2023/NĐ-CP về bảo vệ dữ liệu cá nhân; xử lý quyền xóa dữ liệu trong 72 giờ.
Tình huống 3 — SaaS B2B và cái bẫy "maintainability vô hình"
Một startup SaaS quản lý kho ở Đà Nẵng phục vụ khách doanh nghiệp Nhật Bản. Functional hoàn hảo, khách hài lòng. Nhưng mỗi lần khách Nhật yêu cầu chỉnh sửa nhỏ, đội dev mất 2 tuần vì code rối, không có test tự động, deploy thủ công. Khách dọa hủy hợp đồng vì "tốc độ phản hồi thay đổi quá chậm".
Vấn đề nằm ở Supportability — nhóm NFR vô hình mà không ai viết ra lúc đầu. BA-từ-dev bổ sung:
- Maintainability: Độ phủ test tự động (code coverage) tối thiểu 70% cho module nghiệp vụ lõi.
- Deployability: Pipeline CI/CD, thời gian từ commit đến production dưới 30 phút.
- Configurability: Quy tắc nghiệp vụ theo từng khách hàng cấu hình được qua admin panel, không cần sửa code.
- Observability: Mọi lỗi production gửi cảnh báo trong 5 phút.
Hướng dẫn từng bước
Đây là quy trình thực dụng để khai thác và đặc tả NFR cho một tính năng hoặc hệ thống.
Bước 1 — Quét qua 7 nhóm FURPS+ như một checklist. Với mỗi FR quan trọng, hỏi lần lượt: Tính năng này cần nhanh đến đâu (Performance)? Cần sẵn sàng bao nhiêu phần trăm (Reliability)? Dễ dùng ra sao (Usability)? Có dữ liệu nhạy cảm cần bảo vệ không (Security)? Đội nào sẽ bảo trì (Supportability)? Có ràng buộc công nghệ/pháp lý nào không ("+")? Checklist này đảm bảo bạn không bỏ sót nhóm nào.
Bước 2 — Khai thác con số từ stakeholder bằng câu hỏi cụ thể. Đừng hỏi "anh muốn hệ thống nhanh không?" (ai cũng trả lời có). Hãy hỏi: "Nếu trang tải mất 5 giây, anh chấp nhận được không? Còn 3 giây? Bao nhiêu người dùng đồng thời vào giờ cao điểm?" Dẫn dắt từ trải nghiệm kinh doanh ra con số kỹ thuật.
Bước 3 — Chuyển mong muốn thành câu NFR testable. Áp công thức "[Thành phần] phải [đặc tính] đạt [giá trị] dưới [điều kiện], đo bằng [phương pháp]". Luôn gắn percentile cho performance.
Bước 4 — Định nghĩa cách kiểm thử và nghiệm thu (acceptance criteria). Mỗi NFR phải kèm cách verify: load test bằng k6/JMeter, security scan bằng OWASP ZAP, accessibility audit bằng Lighthouse. Nếu không nói được cách test, NFR đó chưa hoàn chỉnh.
Bước 5 — Ưu tiên và đàm phán đánh đổi (trade-off). NFR luôn xung đột nhau và xung đột với chi phí. Uptime 99,99% đắt gấp nhiều lần 99,9%. Hãy phân loại NFR theo MoSCoW và làm rõ với stakeholder rằng tăng một "-ility" thường tốn tiền hoặc hy sinh "-ility" khác.
Bước 6 — Ghi vào tài liệu đúng chỗ. NFR có thể nằm trong mục riêng của SRS, hoặc gắn vào Definition of Done của các user story, hoặc thành một "NFR backlog" riêng. Quan trọng là chúng phải hiển hiện, không nằm trong đầu ai đó.
Lỗi thường gặp & mẹo
Lỗi 1 — Viết NFR không đo lường được. "Nhanh", "thân thiện", "ổn định" là mong muốn, không phải requirement. Mẹo: nếu không gắn được con số và phương pháp đo, đừng đưa vào tài liệu — hãy quay lại bước khai thác.
Lỗi 2 — Bỏ quên percentile, chỉ dùng trung bình. Trung bình che giấu đuôi phân phối. Mẹo: mặc định dùng p95 cho web, p99 cho API tài chính/giao dịch.
Lỗi 3 — Gom hết security vào một dòng "phải bảo mật". Mẹo: tách nhỏ theo authentication, authorization, encryption (in transit/at rest), audit, compliance — mỗi cái một dòng đo được.
Lỗi 4 — Đặt NFR phi thực tế để "cho chắc". Yêu cầu uptime 99,999% (5 phút downtime/năm) cho một app nội bộ là lãng phí tiền tỷ. Mẹo: NFR phải tương xứng với giá trị kinh doanh và ngân sách. Hỏi "downtime một giờ thiệt hại bao nhiêu?" để định cỡ hợp lý.
Lỗi 5 — Quên nhóm Supportability vì nó vô hình với khách hàng. Mẹo: lấy chính nỗi đau dev cũ của bạn (deploy thủ công, không test, không log) làm checklist maintainability.
Mẹo lợi thế dev: Khi đội dev đẩy lùi một NFR ("không khả thi đâu"), bạn đủ ngôn ngữ kỹ thuật để hỏi "vì sao?", "bottleneck ở đâu?", "nếu thêm cache/CDN/index thì sao?". BA thuần kinh doanh chỉ biết gật. Đây chính là vũ khí khác biệt của bạn.
Bài tập thực hành
Bài 1 — Viết lại cho đo được. Cho ba NFR mơ hồ sau, viết lại mỗi cái theo công thức testable (gắn con số, điều kiện, phương pháp đo và percentile khi phù hợp):
- "Trang tìm kiếm phải nhanh."
- "Hệ thống phải luôn sẵn sàng."
- "Dữ liệu thanh toán phải an toàn."
Bài 3 — Đàm phán trade-off. Stakeholder yêu cầu đồng thời: uptime 99,99%, chi phí hạ tầng giảm 30%, và thời gian phản hồi p99 dưới 200ms. Viết một đoạn ngắn (5–7 câu) giải thích các xung đột giữa ba mục tiêu này và đề xuất một phương án ưu tiên dùng MoSCoW.
Bài 4 — Tình huống Việt Nam. Một app gọi xe muốn mở rộng ra 5 tỉnh. Viết 5 NFR liên quan đến compliance và reliability có dẫn chiếu ít nhất một văn bản pháp lý Việt Nam phù hợp.
Tóm tắt
NFR là phần quyết định một hệ thống tốt hay tệ khi đã chạy đúng chức năng — và đây là sân chơi nơi nền tảng dev của bạn tỏa sáng. Hãy ghi nhớ:
- FURPS+ là bản đồ 7 nhóm: Functionality (gồm security), Usability, Reliability, Performance, Supportability, cộng các ràng buộc thiết kế/pháp lý ("+").
- Mỗi NFR phải đo lường được: gắn con số, điều kiện, percentile và phương pháp kiểm thử. Không đo được thì chưa phải NFR.
- "Bảo mật" và "hiệu năng" không phải một dòng — chúng là danh mục gồm nhiều NFR cụ thể.
- NFR luôn có trade-off với chi phí và với nhau; vai trò BA là làm rõ đánh đổi và ưu tiên theo giá trị kinh doanh.
- Ở Việt Nam, Compliance (Nghị định 13/2023, Quyết định 2345 của NHNN) ngày càng quan trọng — NFR phải dẫn chiếu đúng văn bản.