Consulting Mindset

Tư duy \"Đơn giản hóa\": Tìm ra giải pháp tinh gọn nhất thay vì phức tạp nhất

7/19/2026 · 11p đọc


title: "Tư duy "Đơn giản hóa": Tìm ra giải pháp tinh gọn nhất thay vì phức tạp nhất"
series: "Thư viện Kỹ năng BA·PO·EA: 45 Bài học Thực chiến"
part: "Phần 3 — Tư duy Chiến lược & Tầm nhìn"
skill_number: 35
audience: "BA, PO, EA & vai trò làm việc trực tiếp với khách hàng"
reading_time: "10 phút đọc"
tags:

  • business-analyst
  • product-owner
  • enterprise-architect
  • tu-duy-don-gian-hoa
  • simplicity
  • kien-truc-phan-mem
  • ra-quyet-dinh

Tư duy "Đơn giản hóa": Tìm ra giải pháp tinh gọn nhất thay vì phức tạp nhất

Bạn có để ý một nghịch lý trong nghề tư vấn CNTT không: giải pháp phức tạp luôn dễ được duyệt hơn giải pháp đơn giản? Một kiến trúc nhiều tầng, nhiều pattern, nhiều "phòng thủ" nghe có vẻ chuyên nghiệp và an toàn, còn phương án gọn nhẹ lại dễ bị nghi ngờ là "làm ẩu" hay "chưa nghĩ hết". Nhưng người làm BA/PO/EA giỏi biết: sự phức tạp không đồng nghĩa với sự chắc chắn — và đôi khi chính nó là rủi ro lớn nhất.

🎯 Kỹ thuật cốt lõi: Loại bỏ trước khi thêm (Subtraction Before Addition)

Nguyên tắc rất đơn giản để phát biểu nhưng khó áp dụng trong thực tế vì nó đi ngược bản năng: trước khi hỏi "cần thêm gì để giải quyết vấn đề này", hãy luôn hỏi "có thể bỏ bớt gì mà vấn đề vẫn được giải quyết".

Lý do bản năng con người (và cả kỹ sư) thiên về cộng thêm là vì cộng thêm luôn cảm thấy an toàn hơn — thêm một lớp validate, thêm một cơ chế cache, thêm một service trung gian, thêm một bảng lookup — mỗi thứ thêm vào đều có vẻ như đang "phòng ngừa" một rủi ro cụ thể. Nhưng ít ai cộng dồn chi phí của việc thêm: mỗi thành phần thêm vào là một điểm có thể lỗi, một thứ phải bảo trì, một thứ người mới phải học, một thứ làm chậm việc ra quyết định sau này.

Áp dụng nguyên tắc này theo quy trình 4 bước, tổng quát hóa để dùng cho bất kỳ đề xuất giải pháp nào (kỹ thuật, quy trình, tổ chức):

  1. Liệt kê từng thành phần của giải pháp đang đề xuất. Không đánh giá ngay, chỉ liệt kê: tầng nào, bước nào, hệ thống nào, quy tắc nào đang có mặt trong phương án.
  2. Với mỗi thành phần, hỏi một câu duy nhất: "Nếu bỏ cái này đi, kịch bản nào sẽ thất bại?" Không phải "nó có ích không" (cái gì cũng có ích ít nhiều) mà là "nó ngăn được thất bại cụ thể nào". Nếu không trả lời được một kịch bản thất bại rõ ràng, cụ thể, có xác suất xảy ra đáng kể — thành phần đó là ứng viên để loại bỏ.
  3. Phân biệt "phòng ngừa rủi ro thật" với "phòng ngừa rủi ro tưởng tượng". Rủi ro thật gắn với dữ liệu, sự cố đã từng xảy ra, hoặc yêu cầu nghiệp vụ đã xác nhận. Rủi ro tưởng tượng là "lỡ sau này...", "biết đâu...", "để cho chắc..." — không có bằng chứng, chỉ có cảm giác bất an.
  4. Thiết kế giải pháp từ phần lõi bắt buộc trước, rồi mới xét thêm từng lớp một cách có ý thức — mỗi lớp thêm vào phải đi kèm một lý do bằng văn bản (ghi trong tài liệu thiết kế), không được thêm "cho chắc" mà không giải trình.

Kỹ thuật này không có nghĩa là luôn chọn phương án rẻ nhất hay tối giản nhất bằng mọi giá — nó có nghĩa là gánh nặng chứng minh (burden of proof) phải đặt lên vai của sự phức tạp, chứ không phải lên vai của sự đơn giản. Mặc định là đơn giản; muốn phức tạp hơn thì phải chứng minh được lý do.

Bối cảnh (Situation)

(Tình huống dưới đây là minh hoạ tổng hợp từ các dự án CNTT/tư vấn phổ biến tại Việt Nam, không phải case cụ thể của công ty nào.)

Một công ty phân phối bán lẻ đang triển khai module đồng bộ tồn kho giữa hệ thống bán hàng tại cửa hàng (POS) và kho trung tâm. Yêu cầu nghiệp vụ, nói gọn, chỉ là: mỗi khi một cửa hàng bán một sản phẩm, số tồn kho trung tâm phải được cập nhật trong vòng vài phút để các cửa hàng khác biết còn hàng hay hết hàng.

Chị H., BA của dự án, ngồi họp kickoff kỹ thuật cùng đội phát triển. Trưởng nhóm kỹ thuật — một anh senior rất giỏi, từng làm ở các dự án quy mô lớn — trình bày phương án: dựng một hệ thống event-driven đầy đủ, dùng message queue phân tán, có cơ chế event sourcing để lưu lại toàn bộ lịch sử thay đổi tồn kho, có saga pattern để xử lý rollback khi đồng bộ thất bại giữa nhiều service, và một lớp cache riêng để tăng tốc đọc dữ liệu tồn kho ở tầng hiển thị.

Nghe qua thì rất "chuẩn kiến trúc". Cả phòng họp gật gù. Nhưng chị H. để ý: công ty này có 12 cửa hàng, tổng số giao dịch bán hàng khoảng vài nghìn đơn/ngày, và đội vận hành hệ thống sau này chỉ có 2 kỹ sư backend kiêm nhiệm nhiều việc khác.

Thách thức (Task)

Cái khó của chị H. không phải là hiểu kỹ thuật — chị hiểu rõ event sourcing, saga pattern là gì và tại sao chúng có giá trị ở quy mô lớn. Cái khó là:

  • Đội kỹ thuật đề xuất phương án này không phải vì ác ý hay cố tình "vẽ việc" — họ thực lòng tin đây là cách làm "chắc chắn", đúng chuẩn, và họ có kinh nghiệm thật với những pattern này ở dự án trước (quy mô khác hẳn).
  • Phản đối một đề xuất kỹ thuật từ chính đội kỹ thuật, với tư cách một BA "không code", rất dễ bị nhìn nhận là lấn sân hoặc thiếu hiểu biết chuyên môn.
  • Áp lực tâm lý "làm cho chắc" rất mạnh: nếu sau này hệ thống lỗi vì thiết kế đơn giản không đủ đáp ứng, chị H. sẽ là người đầu tiên bị hỏi "sao lúc đó không làm chắc chắn hơn". Trong khi nếu hệ thống phức tạp bị trễ tiến độ hoặc khó bảo trì, trách nhiệm sẽ mơ hồ hơn, chia đều cho "kỹ thuật khó".
  • Nếu chị H. không lên tiếng, dự án 3 tháng sẽ tiêu tốn ít nhất 6-7 tuần chỉ để dựng hạ tầng message queue, event store, và huấn luyện đội vận hành vốn chỉ có 2 người vốn dĩ chưa từng vận hành kiến trúc phân tán dạng này — rủi ro thực sự nằm ở đây, không phải ở việc tồn kho đồng bộ chậm vài giây.

Hành động (Action)

Chị H. không phản bác trực tiếp bằng cảm tính ("nghe phức tạp quá"), mà áp dụng kỹ thuật loại bỏ trước khi thêm một cách có cấu trúc, ngay trong buổi họp và các buổi làm việc tiếp theo.

Bước 1 — Liệt kê từng thành phần cùng đội kỹ thuật, công khai trên bảng. Chị H. đề nghị anh trưởng nhóm liệt kê lại kiến trúc thành từng khối riêng biệt lên whiteboard: (1) message queue phân tán, (2) event sourcing lưu toàn bộ lịch sử, (3) saga pattern xử lý rollback đa service, (4) lớp cache riêng cho tầng đọc. Chị chủ động ghi lại, không tranh luận ngay, để cả phòng nhìn thấy rõ giải pháp gồm bao nhiêu lớp.

Bước 2 — Hỏi từng thành phần một câu duy nhất: "Nếu bỏ cái này, kịch bản nào thất bại?" Với message queue phân tán, chị hỏi: "Với 12 cửa hàng và vài nghìn đơn/ngày, một API đồng bộ trực tiếp có gọi kịp không?" — câu trả lời từ chính đội kỹ thuật là "có, dư sức". Với event sourcing, chị hỏi: "Nghiệp vụ có yêu cầu xem lại lịch sử thay đổi tồn kho theo từng sự kiện không, hay chỉ cần số tồn kho hiện tại đúng?" — câu trả lời là chỉ cần đúng số hiện tại, chưa có yêu cầu audit lịch sử chi tiết. Với saga pattern, chị hỏi: "Có bao nhiêu service tham gia vào một giao dịch bán hàng?" — câu trả lời: chỉ 2 (POS và kho trung tâm), không cần điều phối nhiều bên.

Bước 3 — Phân loại rủi ro thật và rủi ro tưởng tượng. Chị H. lập một bảng ngắn, hai cột: "Rủi ro có bằng chứng" và "Rủi ro giả định". Cột đầu chỉ có đúng một dòng: độ trễ đồng bộ phải dưới vài phút (đã xác nhận với chủ shop). Cột sau ghi lại các lý do đội kỹ thuật đưa ra: "lỡ sau này công ty mở rộng lên 100 cửa hàng thì sao", "lỡ cần audit trail sau này thì sao". Chị H. không bác bỏ các giả định này, mà đặt câu hỏi ngược: "Nếu điều đó xảy ra, chi phí để nâng cấp lúc đó là bao nhiêu, so với chi phí xây sẵn từ bây giờ mà chưa chắc dùng đến?"

Bước 4 — Đề xuất phương án lõi trước, rồi thương lượng lớp thêm có điều kiện. Chị H. đề xuất: dùng một API đồng bộ đơn giản (REST call trực tiếp khi bán hàng, có retry và alert khi lỗi), lưu log giao dịch trong bảng database thông thường (đủ để tra cứu nếu cần, chưa cần event store chuyên dụng), không cần saga vì chỉ có 2 hệ thống tham gia. Đồng thời, chị không nói "không bao giờ cần message queue" — chị đề xuất ghi rõ trong tài liệu thiết kế một mục "Điều kiện nâng cấp": nếu số cửa hàng vượt quá X, hoặc yêu cầu audit trail xuất hiện, hoặc tần suất lỗi đồng bộ vượt ngưỡng Y, thì đội sẽ quay lại xem xét message queue. Cách này giúp đội kỹ thuật không cảm thấy ý kiến của họ bị bác bỏ hoàn toàn, mà được "gác lại có điều kiện" — điều này giảm hẳn cảm giác bị lấn sân chuyên môn.

Bước 5 — Bảo vệ phương án trước áp lực "làm cho chắc". Khi trưởng phòng kỹ thuật lo ngại "sau này sếp hỏi sao không làm chắc ngay từ đầu", chị H. chuẩn bị sẵn một câu trả lời bằng dữ liệu, không bằng cảm tính: bảng so sánh thời gian triển khai (3 tuần so với 7 tuần), số nhân sự cần để vận hành lâu dài (1 người so với cần ít nhất 2 người có kinh nghiệm hệ thống phân tán), và điều kiện nâng cấp đã ghi rõ trong tài liệu — nghĩa là rủi ro tương lai đã được tính đến, chỉ là chưa trả tiền trước cho một tương lai chưa chắc xảy ra.

Kết quả (Result)

Đội dự án chọn phương án đồng bộ trực tiếp đơn giản. Thời gian xây dựng module giảm từ khoảng 7 tuần dự kiến xuống còn khoảng 3 tuần, giúp dự án có thêm thời gian đệm để xử lý các phần khác đang chậm tiến độ. Đội vận hành 2 người tiếp quản hệ thống không gặp khó khăn lớn vì kiến trúc dễ hiểu, dễ debug khi có sự cố (một luồng gọi trực tiếp, không phải lần theo message qua nhiều hàng đợi).

Điều không hoàn hảo: khoảng 4 tháng sau khi vận hành, công ty mở thêm 5 cửa hàng mới và có yêu cầu mới từ phòng tài chính muốn xem lại lịch sử thay đổi tồn kho theo từng giao dịch để đối soát cuối tháng — đúng một trong hai "điều kiện nâng cấp" đã ghi trong tài liệu thiết kế ban đầu. Đội phải bổ sung một lớp ghi log chi tiết hơn, mất thêm khoảng 1 tuần. Nhưng vì điều kiện này đã được dự liệu và ghi rõ từ đầu, việc bổ sung diễn ra có kế hoạch, không phải xử lý khủng hoảng, và không ai đặt câu hỏi ngược "sao lúc đó không làm chắc ngay từ đầu" — vì câu trả lời đã có sẵn trong tài liệu.

📋 Áp dụng ngay

  • Trước khi duyệt bất kỳ đề xuất giải pháp kỹ thuật hay quy trình nào, yêu cầu liệt kê từng thành phần riêng biệt lên giấy/bảng — đừng đánh giá một "khối" giải pháp gộp chung.
  • Với mỗi thành phần, tự hỏi và hỏi người đề xuất: "Nếu bỏ cái này, kịch bản cụ thể nào sẽ thất bại?" — nếu không ai trả lời được bằng một tình huống cụ thể, đó là ứng viên cắt bỏ.
  • Lập bảng phân loại rủi ro thật (có bằng chứng, có yêu cầu nghiệp vụ xác nhận) và rủi ro tưởng tượng (dựa trên "lỡ", "biết đâu") — chỉ đầu tư cho rủi ro thật.
  • Khi phải gác lại một đề xuất phức tạp hơn, đừng bác bỏ hoàn toàn — ghi rõ "điều kiện nâng cấp" trong tài liệu thiết kế để người đề xuất không cảm thấy bị phủ nhận, và để chính bạn có câu trả lời sẵn khi tương lai đó xảy ra.
  • Chuẩn bị dữ liệu so sánh cụ thể (thời gian, nhân sự, chi phí vận hành) trước khi bảo vệ phương án đơn giản trước áp lực "làm cho chắc" — đừng chỉ dựa vào cảm giác "đơn giản là tốt hơn".

💡 Bài học đúc rút: Sự phức tạp không phải là bằng chứng của sự cẩn trọng — nó thường chỉ là nỗi sợ được ngụy trang thành kiến trúc. Người BA/PO/EA giỏi không hỏi "còn thiếu gì để chắc chắn hơn", mà hỏi "cái gì đang có mặt mà không ai chứng minh được lý do" — và gánh nặng chứng minh luôn phải thuộc về sự phức tạp, không phải sự đơn giản.

🔗 Kỹ năng liên quan


Bài trước: Cách trình bày phương án (Pitching) · Bài tiếp theo: Xây dựng lộ trình (Roadmap) dài hạn

Tư duy \"Đơn giản hóa\": Tìm ra giải pháp tinh gọn nhất thay vì phức tạp nhất