Mở đầu — vì sao bài này quan trọng
Hãy hình dung bạn là Product Owner của một đội phát triển tại một ngân hàng số ở TP.HCM. Trong Sprint Planning, đội mở Backlog ra và gặp một item: "Là khách hàng, tôi muốn mở tài khoản tiết kiệm online để không phải ra quầy". Nghe rất hợp lý. Nhưng khi đội ngồi estimate, con số nhảy lên 21 điểm — gần như nuốt trọn cả Sprint hai tuần. Developer thì lắc đầu vì không biết bắt đầu từ đâu, tester thì không hình dung nổi sẽ test cái gì cho đến tận ngày cuối, còn bạn thì lo lắng vì nếu item này "trượt", cả Sprint coi như không giao được gì có thể demo.
Đây chính là vấn đề mà bài học hôm nay giải quyết: kỹ năng chia nhỏ User Story (Story Splitting) — và quan trọng hơn, chia nhỏ theo chiều dọc (Vertical Slicing) chứ không phải chiều ngang.
Nhiều người nghĩ đây là việc của developer hoặc của Scrum Master. Sai lầm. Story Splitting là một trong những kỹ năng cốt lõi nhất của Product Owner. Bởi vì khi bạn chia một story to thành những lát mỏng có giá trị, bạn đang đồng thời làm ba việc: (1) giúp đội ước lượng và lập kế hoạch chính xác hơn, (2) tạo ra cơ hội nhận phản hồi sớm từ thị trường, và (3) bảo vệ giá trị kinh doanh bằng cách giao được "thứ gì đó dùng được" thay vì "một nửa mọi thứ chưa dùng được gì". PO nào không biết split story sẽ luôn bị động, luôn để backlog ứ đọng những tảng đá khổng lồ, và luôn phải xin lỗi stakeholder vì "Sprint này chưa xong".
Bài này sẽ dạy bạn cách suy nghĩ và thực hành để biến mọi tảng đá thành những viên gạch nhỏ vừa tay.
Khái niệm cốt lõi
Tại sao phải split story?
Một story quá lớn (thường gọi là Epic, hoặc đơn giản là "big story") gây ra hàng loạt hệ lụy mà PO phải gánh chịu:
- Khó ước lượng: Việc càng lớn, độ bất định càng cao, sai số estimate càng lớn. Một story 21 điểm thực tế có thể là 13 hoặc 40 — không ai biết chắc.
- Khó test và khó review: Tester không thể bắt đầu cho đến khi mọi thứ gần như hoàn thành, dồn rủi ro về cuối Sprint.
- Dễ trượt Sprint: Nếu story chiếm phần lớn dung lượng Sprint mà chưa "Done", bạn không có gì để demo ở Sprint Review.
- Phản hồi đến muộn: Bạn phải chờ rất lâu mới biết liệu mình có đang xây đúng thứ khách hàng cần hay không.
- Che giấu rủi ro: Một item to thường gói nhiều giả định chưa kiểm chứng. Khi vỡ ra, nó vỡ to.
Vertical slicing vs Horizontal slicing — trái tim của bài học
Đây là khái niệm quan trọng nhất bạn cần nắm.
Horizontal slicing (cắt ngang theo tầng kỹ thuật) là cách chia story theo các lớp công nghệ:
- Một story làm phần database.
- Một story làm phần backend/API.
- Một story làm phần giao diện (UI).
- Một story làm phần tích hợp.
Vertical slicing (cắt dọc xuyên qua mọi tầng) thì ngược lại. Mỗi lát mỏng đi xuyên qua tất cả các tầng — từ UI, qua logic nghiệp vụ, xuống database — nhưng chỉ cho một phần nhỏ chức năng. Kết quả là mỗi lát đều chạy được, demo được, và mang lại giá trị thật.
Hãy hình dung một chiếc bánh kem nhiều tầng. Cắt ngang nghĩa là bạn lấy riêng tầng cốt bánh, riêng tầng kem, riêng tầng dâu — chẳng ai ăn được. Cắt dọc nghĩa là bạn lấy một miếng nhỏ có đủ cả cốt, kem và dâu — ăn được ngay, và biết ngay bánh ngon hay dở. Vertical slicing là cắt dọc chiếc bánh.
Quay lại ví dụ "mở tài khoản tiết kiệm online". Cắt dọc có thể là:
- Lát 1: Mở tài khoản với kỳ hạn cố định 6 tháng, lãi suất mặc định, chỉ một loại tiền VND — đi đủ từ màn hình nhập đến lưu vào hệ thống và hiện xác nhận.
- Lát 2: Bổ sung cho phép chọn nhiều kỳ hạn.
- Lát 3: Bổ sung gửi email/SMS xác nhận.
- Lát 4: Bổ sung eKYC nâng cao cho khoản tiền lớn.
Các mẫu (pattern) chia nhỏ thường dùng
Để không bị "bí" khi đứng trước một story to, bạn nên thuộc nắm lòng vài mẫu chia dọc kinh điển (lấy cảm hứng từ bộ pattern của Richard Lawrence):
- Theo bước trong quy trình (Workflow Steps): Tách các bước của một luồng dài. Ví dụ luồng đặt hàng: chọn sản phẩm → giỏ hàng → thanh toán → xác nhận. Làm trước luồng "happy path" đơn giản nhất.
- Theo quy tắc nghiệp vụ (Business Rule Variations): Làm trước trường hợp đơn giản, sau đó bổ sung các biến thể quy tắc. Ví dụ: tính phí ship mặc định trước, rồi mới thêm khuyến mãi, miễn phí ship theo vùng, theo hạng thành viên.
- Theo trường hợp đơn giản vs phức tạp (Happy Path first): Làm đường đi thành công trước, xử lý lỗi và ngoại lệ sau.
- Theo biến thể dữ liệu / loại đầu vào (Data Variations): Hỗ trợ một loại dữ liệu trước (chỉ thẻ Visa), rồi mở rộng (Mastercard, JCB, ví điện tử).
- Theo thao tác CRUD (Operations): Tách Create, Read, Update, Delete thành các story riêng nếu chúng đủ giá trị độc lập.
- Theo giao diện / kênh (Interface Variations): Làm web trước, mobile sau; hoặc làm phiên bản giao diện thô trước, đẹp sau.
- Trì hoãn hiệu năng (Defer Performance): Làm cho nó chạy đúng trước, chạy nhanh sau.
Tình huống thực tế
Ví dụ 1 — Sàn TMĐT "ChợViệt": cái bẫy cắt ngang
ChợViệt là một sàn thương mại điện tử giả định tại Hà Nội, đội Scrum 7 người. Họ nhận story: "Là người mua, tôi muốn thanh toán đơn hàng bằng nhiều phương thức (thẻ ngân hàng, ví MoMo, ZaloPay, COD) để thuận tiện". Estimate ban đầu: 34 điểm.
PO lúc đầu chia theo kiểu cắt ngang: một story "thiết kế bảng giao dịch trong DB", một story "xây API cổng thanh toán chung", một story "làm màn hình chọn phương thức". Sau Sprint đầu, đội báo cáo: DB và API đã xong, nhưng vì chưa có tích hợp cổng thật và chưa có UI hoàn chỉnh, không thể demo việc thanh toán nào. Stakeholder kinh doanh dự Sprint Review ra về với khuôn mặt thất vọng vì "hai tuần mà chưa thanh toán được đồng nào".
PO nhận ra sai lầm và chuyển sang cắt dọc theo biến thể dữ liệu (phương thức thanh toán):
- Lát 1 (5 điểm): Thanh toán COD — đơn giản nhất, đi đủ từ UI chọn COD → ghi nhận đơn → xác nhận. Release ngay, khách dùng được liền.
- Lát 2 (8 điểm): Tích hợp MoMo (phương thức phổ biến nhất với người mua trẻ).
- Lát 3 (8 điểm): Tích hợp ZaloPay.
- Lát 4 (8 điểm): Thanh toán thẻ ngân hàng qua cổng.
Ví dụ 2 — Startup giao đồ ăn "GrabBites": chia theo happy path và quy tắc nghiệp vụ
Một startup giao đồ ăn ở Đông Nam Á (gọi là GrabBites) có story: "Là khách, tôi muốn áp mã giảm giá khi đặt món để tiết kiệm tiền". Nghe nhỏ, nhưng khi đào sâu, đội phát hiện nó chứa hàng loạt quy tắc: mã theo phần trăm, mã theo số tiền cố định, mã miễn phí ship, mã theo nhà hàng cụ thể, mã chỉ cho khách mới, mã có giá trị đơn tối thiểu, mã hết hạn, mã giới hạn số lần dùng... Estimate phình lên 20 điểm.
PO áp dụng mẫu happy path + biến thể quy tắc nghiệp vụ:
- Lát 1 (3 điểm): Áp mã giảm theo số tiền cố định, hợp lệ, không điều kiện. Đường đi thành công đơn giản nhất. Đây đã là một tính năng có thể marketing được.
- Lát 2 (3 điểm): Thêm mã giảm theo phần trăm.
- Lát 3 (5 điểm): Thêm điều kiện giá trị đơn tối thiểu và ngày hết hạn.
- Lát 4 (3 điểm): Thêm giới hạn số lần sử dụng.
- Lát 5 (5 điểm): Thêm mã chỉ dành cho khách hàng mới (cần kiểm tra lịch sử mua).
Ví dụ 3 — Ngân hàng số: trì hoãn hiệu năng và tách báo cáo
Quay lại ngân hàng số ở TP.HCM. Họ có story: "Là quản lý chi nhánh, tôi muốn xem báo cáo giao dịch theo thời gian thực với bộ lọc đa chiều để giám sát rủi ro". Estimate: 21 điểm, một phần lớn nằm ở yêu cầu "thời gian thực" và "đa chiều".
PO áp dụng kết hợp hai mẫu: tách thao tác đọc đơn giản và trì hoãn hiệu năng:
- Lát 1 (5 điểm): Báo cáo giao dịch trong ngày, không lọc, dữ liệu cập nhật mỗi 15 phút (chưa real-time). Quản lý đã có thứ để xem.
- Lát 2 (5 điểm): Thêm bộ lọc theo chi nhánh và loại giao dịch.
- Lát 3 (8 điểm): Nâng cấp lên real-time (đây là phần khó về kỹ thuật, được tách riêng).
- Lát 4 (3 điểm): Thêm xuất Excel/PDF.
Hướng dẫn từng bước
Đây là quy trình thực hành bạn có thể áp dụng cho bất kỳ story to nào, thường làm trong buổi Backlog Refinement cùng đội:
- Nhận diện story cần split. Dấu hiệu: estimate vượt khoảng một nửa năng lực Sprint, hoặc đội tranh luận mãi không estimate được, hoặc story có chữ "và", "hoặc", "tất cả", "đa dạng" trong mô tả.
- Tìm "đường xương sống" (walking skeleton). Hỏi: "Phiên bản đơn giản nhất, mỏng nhất nhưng vẫn dùng được của tính năng này là gì?" Đó chính là lát đầu tiên. Nó phải đi xuyên đủ các tầng.
- Chọn mẫu chia phù hợp. Lướt qua danh sách 7 mẫu ở trên. Tự hỏi: story này biến thiên theo điều gì nhiều nhất — theo bước quy trình? theo quy tắc? theo loại dữ liệu? Đó là trục để cắt.
- Cắt thành 2–5 lát dọc. Đừng cắt quá vụn (quản lý mệt) cũng đừng quá to. Mỗi lát lý tưởng là 1–8 điểm, đủ làm xong gọn trong Sprint.
- Kiểm tra từng lát bằng INVEST, đặc biệt chữ V: "Lát này có thể demo và có người dùng nó không?" Nếu câu trả lời là "không, phải chờ lát khác mới dùng được" — bạn đang lỡ cắt ngang, hãy cắt lại.
- Xếp thứ tự (Order) các lát theo giá trị và rủi ro. Thường đưa lát giá trị cao / rủi ro cao / học được nhiều nhất lên trước. (Lưu ý: đây là ordering chứ không đơn thuần là prioritization — chủ đề được bàn kỹ ở bài khác.)
- Cập nhật Backlog: thay story to bằng các lát, ghi rõ Acceptance Criteria cho từng lát.
Lỗi thường gặp & mẹo
Lỗi 1 — Cắt ngang theo tầng kỹ thuật. Đây là lỗi phổ biến nhất. Dấu hiệu: tên story là "Làm API...", "Thiết kế database cho...", "Dựng UI cho...". Khắc phục: luôn hỏi "ai sẽ dùng được lát này, và dùng để làm gì?". Nếu không trả lời được, đó là lát ngang.
Lỗi 2 — Lát mất giá trị (đánh rơi chữ V). Cắt nhỏ đến mức lát đầu tiên chẳng làm được gì có ý nghĩa. Mẹo: lát mỏng nhất vẫn phải kể được một câu chuyện hoàn chỉnh cho người dùng, dù là phiên bản nghèo nàn nhất.
Lỗi 3 — Tách thành "task" thay vì "story". "Viết unit test", "Refactor service" là task kỹ thuật, không phải lát giá trị. Split là chia theo giá trị người dùng, không phải chia theo công việc kỹ thuật.
Lỗi 4 — Split quá muộn, ngay trong Sprint Planning. Khi đó đã quá trễ, gây áp lực. Mẹo: split là việc của Refinement, làm đều đặn trước Planning ít nhất một Sprint.
Lỗi 5 — PO tự split một mình rồi áp xuống đội. Developer hiểu kiến trúc kỹ thuật, họ thường nhìn ra cách cắt thông minh mà bạn không thấy. Split là hoạt động cộng tác. PO mang góc nhìn giá trị, đội mang góc nhìn khả thi.
Mẹo vàng — "Spike" cho phần bất định. Nếu một lát quá mơ hồ về kỹ thuật đến mức không cắt nổi, đôi khi cần một spike (một timebox nghiên cứu) trước. Tuy nhiên kỹ thuật Spike và Hamburger Method là chủ đề của bài kế tiếp, nên ở đây chỉ cần nhớ: khi không split được vì thiếu hiểu biết, hãy đi tìm hiểu biết trước.
Bài tập thực hành
Hãy luyện tập với story sau (lấy bối cảnh Việt Nam):
> "Là người dùng ứng dụng đặt vé xe khách liên tỉnh, tôi muốn tìm và đặt vé cho chuyến đi của mình để không phải ra bến mua vé."
Estimate ban đầu: 21 điểm. Nhiệm vụ của bạn:
- Liệt kê các yếu tố biến thiên trong story này (gợi ý: tìm theo gì? lọc theo gì? thanh toán ra sao? chọn ghế hay không?).
- Chọn ít nhất hai mẫu chia từ danh sách 7 mẫu và áp dụng.
- Viết ra 4–5 lát dọc, mỗi lát kèm một câu Acceptance Criteria. Lát đầu tiên phải là "walking skeleton" — mỏng nhất nhưng vẫn đặt được vé thật.
- Tự kiểm INVEST cho từng lát: đánh dấu lát nào bạn nghi ngờ là cắt ngang và sửa lại.
- Xếp thứ tự các lát và viết một câu lý giải vì sao lát số 1 lên đầu.
Làm xong, hãy mang kết quả ra thảo luận với một developer thật. Bạn sẽ ngạc nhiên về những cách cắt mà chỉ khi cộng tác mới lộ ra.
Tóm tắt
- Story to gây khó estimate, khó test, dễ trượt Sprint và làm chậm phản hồi. Splitting là kỹ năng cốt lõi của PO để đạt chữ S — Small trong INVEST.
- Vertical slicing (cắt dọc) là nguyên tắc tối thượng: mỗi lát đi xuyên đủ các tầng và mang giá trị dùng được. Tránh horizontal slicing (cắt ngang theo tầng kỹ thuật) vì nó đánh mất chữ V — Valuable.
- Thuộc lòng 7 mẫu chia: theo bước quy trình, theo quy tắc nghiệp vụ, happy path trước, theo biến thể dữ liệu, theo thao tác CRUD, theo giao diện/kênh, và trì hoãn hiệu năng.
- Quy trình: nhận diện → tìm walking skeleton → chọn mẫu → cắt 2–5 lát → kiểm INVEST → xếp thứ tự → cập nhật Backlog. Làm trong Refinement, làm cùng đội.
- Split tốt không chỉ giúp giao giá trị sớm mà còn cô lập rủi ro và cung cấp dữ liệu để ra quyết định ưu tiên — như ChợViệt phát hiện COD chiếm 60%, hay ngân hàng nhận ra 15 phút là đủ thay vì real-time.