Mở đầu — vì sao bài này quan trọng
Nếu bạn đã từng viết code, hẳn bạn nhớ cảm giác này: một if-else nhỏ xíu bị nhét sâu trong một service, ba tháng sau không ai biết tại sao nó tồn tại, và khi business muốn đổi từ "giảm giá 10% cho đơn trên 500k" sang "giảm 15% cho đơn trên 1 triệu", cả team phải đào lại source code, sửa, test, deploy — mất nửa ngày cho một thay đổi mà sếp tưởng chỉ cần 5 phút.
Đó chính xác là vấn đề mà Business Rules (quy tắc kinh doanh) ra đời để giải quyết. Và đây là một trong những lĩnh vực mà bạn — một developer chuyển sang BA — có lợi thế cực lớn, nhưng cũng dễ mắc bẫy nhất.
Lợi thế: bạn hiểu logic nằm ở đâu trong hệ thống, bạn biết một business rule khi được "hard-code" sẽ gây đau như thế nào. Cái bẫy: bạn có xu hướng nghĩ business rule chính là code, và viết nó ra dưới dạng pseudo-code thay vì ngôn ngữ business. Bài học hôm nay sẽ giúp bạn tách bạch rõ ràng: business rule là tài sản của business, không phải của developer. Nhiệm vụ của BA là phát hiện, đặt tên, phân loại và quản lý chúng tách rời khỏi code — để business có thể đọc, hiểu và thay đổi mà không cần đụng đến một dòng lập trình.
Đây cũng là kỹ năng phân biệt một BA "viết lại requirement" với một BA thực sự kiểm soát được hành vi của hệ thống.
Khái niệm cốt lõi
Business Rule là gì?
Theo định nghĩa kinh điển của Ronald Ross (cha đẻ của ngành Business Rules) và BABOK v3, một business rule là:
> Một chỉ thị cụ thể, có thể kiểm chứng, ràng buộc hoặc định nghĩa một khía cạnh nào đó của hoạt động kinh doanh — nhằm duy trì cấu trúc của business hoặc kiểm soát/chi phối hành vi của nó.
Hãy bóc tách câu này. Một business rule không phải là một tính năng (feature), không phải là một bước trong quy trình (process step), và tuyệt đối không phải là code. Nó là một mệnh đề mang tính chân lý của business, đúng bất kể hệ thống được xây bằng Java hay PHP, bất kể quy trình chạy thủ công hay tự động.
Ví dụ phân biệt nhanh:
- "Khách hàng nhập email rồi bấm Đăng ký" → đây là process step, không phải rule.
- "Hệ thống có nút Đăng ký màu xanh" → đây là feature/UI, không phải rule.
- "Một email chỉ được dùng để đăng ký tối đa một tài khoản" → đây mới là business rule. Nó đúng dù bạn code thế nào, dù form trông ra sao.
Vì sao phải "tách logic khỏi code"?
Nguyên lý nền tảng ở đây gọi là externalization — đưa business rule ra ngoài, tách khỏi logic kỹ thuật. Lý do:
- Business rule thay đổi nhanh hơn code rất nhiều. Lãi suất, hạn mức, ngưỡng giảm giá, điều kiện duyệt hồ sơ — những thứ này đổi theo quý, theo chiến dịch, theo quy định pháp luật. Code thì ổn định hàng năm.
- Người thay đổi rule không phải developer. Đó là trưởng phòng tín dụng, là manager marketing, là bộ phận pháp chế. Họ cần đọc hiểu được rule mà không cần biết lập trình.
- Cùng một rule áp dụng ở nhiều nơi. Nếu hard-code, bạn sẽ copy-paste logic "đơn hàng tối thiểu 50.000đ" vào 5 chỗ khác nhau, và đến lúc đổi sẽ sót 2 chỗ.
Phân loại 4 loại của Ronald Ross
Ronald Ross chia business rules thành bốn nhóm chính. Nắm vững phân loại này giúp bạn phát hiện rule một cách có hệ thống thay vì bắt gặp ngẫu nhiên.
1. Definitional rules / Structural rules (Quy tắc định nghĩa — cấu trúc) Đây là những rule định nghĩa khái niệm, phân loại, hoặc tính toán. Chúng nói "cái gì là cái gì". Ví dụ: "Khách hàng VIP là khách hàng có tổng giá trị đơn hàng trong 12 tháng gần nhất từ 50 triệu đồng trở lên." Hay: "Tổng tiền đơn hàng = tổng giá trị các sản phẩm + phí vận chuyển − giá trị khuyến mãi." Loại rule này không thể bị "vi phạm" — nó đơn giản là định nghĩa.
2. Operative rules / Behavioral rules (Quy tắc vận hành — hành vi) Đây là những rule ràng buộc hành vi, có thể bị vi phạm và do đó cần xử lý khi vi phạm. Ví dụ: "Một tài khoản không được rút vượt quá số dư khả dụng." Hoặc: "Đơn hàng phải được thanh toán trong vòng 24 giờ, nếu không sẽ tự động hủy." Loại này luôn cần đi kèm một enforcement level — mức độ thực thi: bắt buộc tuyệt đối (strictly enforced), cho phép ngoại lệ có phê duyệt (override với approval), hay chỉ cảnh báo (guideline).
Hai loại còn lại thường được nhóm gộp trong thực hành:
3. Constraints / Validation rules (Ràng buộc — kiểm tra hợp lệ) Giới hạn giá trị dữ liệu được chấp nhận. Ví dụ: "Số CMND/CCCD phải đủ 12 chữ số." "Ngày sinh không được là ngày trong tương lai."
4. Computation / Derivation rules (Quy tắc tính toán — suy diễn) Quy tắc tính ra giá trị mới từ dữ liệu sẵn có. Ví dụ: "Phí trễ hạn = 2% × số tiền chưa thanh toán × số ngày trễ."
Trong thực tế làm việc tại Việt Nam, bạn không cần quá cứng nhắc với việc một rule rơi đúng vào ô nào. Điều quan trọng hơn là dùng phân loại này như một checklist phát hiện rule khi phỏng vấn stakeholder.
Cấu trúc một business rule tốt
Một business rule được viết tốt nên có các thành phần sau (tôi đề xuất template này cho hầu hết dự án):
| Trường | Nội dung |
|---|---|
| ID | BR-001 (mã duy nhất, trace được) |
| Tên | Ngắn gọn, dễ nhớ |
| Phát biểu | Câu khẳng định rõ ràng, dùng từ "phải / không được / nếu... thì" |
| Loại | Definitional / Operative / Constraint / Computation |
| Enforcement | Mức độ thực thi (bắt buộc / cho phép override / cảnh báo) |
| Nguồn | Ai/quy định nào đặt ra rule này (phòng ban, văn bản pháp luật) |
| Liên quan | Use case / user story nào dùng rule này |
Tình huống thực tế
Tình huống 1 — Sàn TMĐT và cái bẫy "giảm giá hard-code"
Một startup TMĐT tại TP.HCM (tạm gọi là ShopFast) có module khuyến mãi. Ban đầu chỉ có một rule đơn giản: "miễn phí ship cho đơn từ 300.000đ". Developer nhét thẳng con số 300000 vào hàm calculateShipping().
Sáu tháng sau, business muốn chạy các chiến dịch dồn dập: tháng 11 ngưỡng là 250k, ngày 12/12 hạ xuống 199k, thành viên VIP thì 0đ, riêng khu vực nội thành Hà Nội và Sài Gòn áp ngưỡng khác. Mỗi lần đổi, marketing phải gửi yêu cầu cho dev, dev sửa code, QA test, rồi deploy — chu kỳ 1-2 ngày. Đỉnh điểm là đợt 12/12, marketing đổi ngưỡng lúc 11 giờ đêm nhưng dev đã về, chiến dịch lệch mất 3 tiếng, ước tính mất khoảng 40 triệu doanh thu.
BA mới vào (vốn là developer cũ) đã làm đúng việc: tách toàn bộ logic khuyến mãi thành một bảng business rules có cấu trúc, với các tham số (ngưỡng tiền, % giảm, nhóm khách, khu vực, thời gian hiệu lực) được mô tả như dữ liệu cấu hình, không phải code. Tài liệu BR nêu rõ: "Các ngưỡng và điều kiện khuyến mãi phải có thể chỉnh sửa bởi team Marketing qua giao diện cấu hình, không cần deploy lại." Dev sau đó xây một bảng cấu hình trong DB + một màn hình admin nhỏ.
Bài học: BA không tự xây rule engine, nhưng chính việc nhận diện rằng đây là business rule hay thay đổi và viết requirement tách nó khỏi code đã định hướng kiến trúc đúng. Lợi thế dev giúp bạn nhìn ra điều này sớm.
Tình huống 2 — Ngân hàng và rule duyệt khoản vay (enforcement level)
Tại một ngân hàng số ở Việt Nam, đội BA làm sản phẩm vay tiêu dùng. Một stakeholder từ phòng tín dụng nói: "Khách phải trên 22 tuổi mới được vay." BA junior ghi luôn: BR: tuổi >= 22.
BA senior (xuất thân dev) hỏi thêm ba câu: "Trên 22 là tính theo ngày sinh hay năm sinh? Có ngoại lệ nào không? Nếu khách 21 tuổi nhưng có người bảo lãnh thì sao?" Hóa ra rule thật phức tạp hơn:
- BR-014: Độ tuổi vay tối thiểu là 20 tuổi (tính tròn theo ngày sinh) tại thời điểm giải ngân. Enforcement: bắt buộc tuyệt đối — đây là quy định theo Thông tư của Ngân hàng Nhà nước.
- BR-015: Khách 20–22 tuổi có hạn mức tối đa 30 triệu. Enforcement: bắt buộc, nhưng giám đốc chi nhánh được override lên 50 triệu nếu có tài sản đảm bảo.
Bài học: Một business rule chưa đủ nếu chưa có enforcement level. Đặc biệt với domain ngân hàng/fintech tại Việt Nam, phải tách rõ rule nào là compliance (bất di bất dịch) và rule nào là policy (chính sách nội bộ, có thể nới).
Tình huống 3 — Logic ẩn trong code legacy mà không ai biết
Một công ty logistics ở Bình Dương có hệ thống tính cước vận chuyển viết từ 2016. Khi BA làm dự án thay thế hệ thống (replatform), họ phát hiện trong code có một đoạn: if (weight > 30 && province == "Cà Mau") fee *= 1.25;.
Không ai trong business hiện tại biết rule này. Hỏi khắp nơi, cuối cùng một anh kho cũ nhớ ra: năm 2016 tuyến Cà Mau phải trung chuyển bằng phà nên cộng phụ phí. Nhưng từ 2022 đã có cầu, phụ phí này lẽ ra phải bỏ — công ty đã âm thầm tính dư cước cho khách hàng tuyến Cà Mau suốt hai năm.
Bài học: Đây là minh họa kinh điển cho hậu quả của việc không tách rule khỏi code. Khi rule sống ẩn trong code, nó trở thành "tribal knowledge" rồi thành "ma trong máy" — không ai sở hữu, không ai review. Một phần việc quan trọng của BA trong dự án migration là khai quật (mining) các business rule đang ẩn trong code legacy, đưa chúng ra ánh sáng, và để business xác nhận từng cái còn hợp lệ hay không.
Hướng dẫn từng bước
Đây là quy trình tôi khuyên bạn áp dụng để phát hiện và quản lý business rules trong một dự án:
Bước 1 — Phát hiện (elicit) rule từ nhiều nguồn. Đừng chờ stakeholder "đọc" rule cho bạn — họ thường không ý thức được mình đang nói ra một rule. Hãy săn rule ở: phỏng vấn nghiệp vụ (lắng nghe các từ "phải", "không được", "trừ khi", "nếu... thì"), văn bản pháp luật/quy định nội bộ, biểu mẫu giấy tờ hiện hành, và đặc biệt — với lợi thế dev của bạn — đọc trực tiếp source code và database constraint của hệ thống cũ.
Bước 2 — Phát biểu rule bằng ngôn ngữ business, atomic. Mỗi rule chỉ nói một điều (atomic). Tránh "khách phải trên 20 tuổi và có CCCD hợp lệ và thu nhập trên 5 triệu" — tách thành ba rule riêng. Viết bằng từ ngữ nghiệp vụ, tránh thuật ngữ kỹ thuật. Dùng mẫu câu: "Một [đối tượng] phải/không được [điều kiện]" hoặc "Nếu [điều kiện] thì [hệ quả]".
Bước 3 — Phân loại và gán enforcement level. Đặt mỗi rule vào một trong 4 loại của Ross, và quan trọng nhất là gán mức thực thi: bắt buộc tuyệt đối, cho phép override (kèm ai được override), hay chỉ hướng dẫn.
Bước 4 — Đánh ID và đưa vào kho rule riêng (Business Rules Catalog). Tạo một danh mục rule tách biệt — một sheet riêng, một trang Confluence riêng, hoặc một bảng trong Notion. Tuyệt đối không để rule chỉ nằm rải rác trong các use case.
Bước 5 — Liên kết (trace) rule với requirement. Trong use case hoặc user story, thay vì viết lại nội dung rule, hãy tham chiếu đến nó: "Bước này áp dụng BR-014, BR-015". Như vậy khi rule đổi, bạn chỉ sửa một chỗ và biết ngay nó ảnh hưởng những use case nào.
Bước 6 — Xác nhận với business và lập kế hoạch quản lý thay đổi. Để stakeholder review từng rule, xác nhận chủ sở hữu (owner) của mỗi rule, và thống nhất ai có quyền thay đổi rule sau này.
Lỗi thường gặp & mẹo
Lỗi 1 — Viết rule như pseudo-code. Đây là bệnh kinh điển của dev mới chuyển BA. Bạn viết BR: IF order.total >= 500000 THEN discount = 0.1. Sai. Business đọc không hiểu, và bạn đang lén lút thiết kế thay vì mô tả. Hãy viết: "Đơn hàng có tổng giá trị từ 500.000đ trở lên được giảm 10%."
Lỗi 2 — Trộn rule vào trong process flow. Đừng nhét rule vào giữa các bước của use case rồi quên đánh dấu. Rule phải có chỗ ở riêng và được tham chiếu.
Lỗi 3 — Quên enforcement level. Như tình huống ngân hàng ở trên: rule không nói rõ có được override không sẽ khiến hệ thống hoặc quá cứng, hoặc quá lỏng.
Lỗi 4 — Rule không atomic. Gộp nhiều điều kiện vào một rule khiến không trace được, không test được riêng lẻ.
Lỗi 5 — Bỏ qua nguồn/owner của rule. Một rule không có chủ sẽ trở thành "ma trong máy" như tình huống logistics. Luôn ghi rõ rule đến từ đâu (văn bản nào, phòng ban nào).
Mẹo vàng: Dùng kỹ thuật "keyword hunting" khi đọc tài liệu và nghe phỏng vấn. Mỗi khi gặp các từ: phải, bắt buộc, không được, tối thiểu, tối đa, ít nhất, trừ khi, ngoại trừ, chỉ khi, nếu… thì, được phép, mặc định — gần như chắc chắn có một business rule đang ẩn sau đó. Dừng lại, đào sâu, đặt mã.
Mẹo tận dụng lợi thế dev: Khi làm dự án thay thế hệ thống cũ, hãy chủ động xin quyền đọc source code và các database constraint (UNIQUE, CHECK, FOREIGN KEY, trigger). Đây là mỏ vàng chứa hàng trăm business rule đã được "đóng băng" trong code mà business hiện tại có thể đã quên. Một BA không biết đọc code sẽ bỏ lỡ hoàn toàn nguồn này.
Bài tập thực hành
Bài 1 — Phân loại. Cho các phát biểu sau, xác định cái nào là business rule, cái nào không (và nếu không thì nó là gì: feature, process step, hay yêu cầu kỹ thuật):
- "Khách hàng bấm nút 'Thanh toán' để hoàn tất đơn."
- "Mã giảm giá chỉ được sử dụng một lần cho mỗi tài khoản."
- "Hệ thống phải phản hồi trong vòng 2 giây."
- "Sinh viên đăng ký quá 24 tín chỉ một học kỳ phải có chữ ký của cố vấn học tập."
- "Trang chủ hiển thị banner khuyến mãi ở đầu trang."
if (booking.checkOut <= booking.checkIn) reject("invalid");
if (booking.nights > 30) requireManagerApproval();
roomPrice = basePrice * (isWeekend ? 1.3 : 1.0);
Bài 3 — Gán enforcement. Lấy một quy trình bạn quen thuộc (ví dụ: chính sách hoàn tiền của một sàn TMĐT bạn hay mua). Liệt kê 5 business rule, và với mỗi rule gán enforcement level (bắt buộc tuyệt đối / cho phép override có duyệt / cảnh báo) cùng lý do.
Bài 4 — Khai quật rule. Nếu bạn còn giữ một project code cũ của mình, hãy mở ra và tìm 3 đoạn if-else chứa "magic number" hoặc điều kiện nghiệp vụ. Viết chúng lại thành business rule chuẩn. Đây là bài tập biến lợi thế dev của bạn thành kỹ năng BA thực sự.
Tóm tắt
Business rule là tài sản của business, không phải của developer: một mệnh đề ràng buộc hoặc định nghĩa hành vi/cấu trúc của business, đúng kể cả khi không có phần mềm. Nhiệm vụ trung tâm của bài này — "tách logic khỏi code" — với vai trò BA nghĩa là: phát hiện rule, viết nó bằng ngôn ngữ business (không phải pseudo-code), phân loại theo 4 nhóm của Ronald Ross (definitional, operative, constraint, computation), gán enforcement level, đánh ID và lưu vào một Business Rules Catalog riêng, rồi trace ngược về các use case/user story.
Là dev chuyển sang BA, bạn có hai siêu năng lực: hiểu nỗi đau của rule bị hard-code, và biết đọc code/DB để khai quật rule ẩn. Nhưng hãy cảnh giác với cái bẫy lớn nhất — viết rule như code. Hãy luôn tự hỏi: "Một người làm nghiệp vụ, không biết lập trình, có đọc rule này và hiểu ngay không?" Nếu có, bạn đã tách thành công logic khỏi code.