Áp Dụng System Design Mindset Vào Công Việc Hằng Ngày — Không Cần Chức Danh Architect

“Mình đâu phải Architect, đâu cần nghĩ mấy chuyện đó” — mình nghe câu này khá nhiều lần từ các bạn dev 1-3 năm kinh nghiệm. Vấn đề là: chờ đến khi có title rồi mới tập tư duy hệ thống thì hơi trễ. Title không tạo ra mindset. Mindset tạo ra title.

bài trước, mình nói về 3 trụ cột của system design mindset: trade-off, boundary, failure-mode. Bài này đi vào phần thực dụng — 7 tips cụ thể để áp dụng ngay trong công việc hằng ngày, kể cả khi bạn chỉ đang nhận ticket từ Jira và chưa từng được giao quyền quyết định kiến trúc.

Nguyên tắc nền: mindset thể hiện qua câu hỏi bạn đặt, không qua quyền hạn bạn có

Bạn không cần quyền phê duyệt kiến trúc để bắt đầu nghĩ như người thiết kế hệ thống. Bạn chỉ cần thay đổi thứ tự câu hỏi: từ “làm sao cho chạy” sang “làm sao cho chạy đúng, và nếu sai thì ai phát hiện ra trước”. Dưới đây là các tip cụ thể.

1. Trước khi code, hỏi “cái gì trong yêu cầu này sẽ đổi trong 3 tháng tới”

Không phải để đoán tương lai chính xác, mà để tránh hard-code những thứ có khả năng thay đổi cao.

Ví dụ khi xây dựng tính năng thanh toán cho một hệ thống bán hàng: nếu mình viết trực tiếp logic xử lý VNPay vào từng component của checkout, đến lúc bổ sung MoMo hoặc thay đổi payment provider, mình sẽ phải sửa rất nhiều nơi. Nếu tách phần xử lý payment ra một layer riêng ngay từ đầu, việc thay đổi provider sẽ đơn giản hơn rất nhiều.

❌ Gọi trực tiếp API VNPay và xử lý response trong từng component checkout
✅ Tách một layer paymentService.pay(order) — thay đổi payment provider chỉ cần xử lý ở layer này

2. Vẽ boundary bằng một câu, trước khi viết function đầu tiên

Trước khi code một tính năng mới, tự trả lời: “module này sở hữu dữ liệu gì, module nào khác được phép đọc, module nào tuyệt đối không được ghi vào đây”. Không cần viết thành tài liệu dài dòng — một dòng comment trên đầu file cũng đủ.

❌ Component frontend tự ý query thẳng database qua một API “tạm thời cho nhanh”
✅ Component chỉ gọi qua API layer đã định nghĩa, kể cả khi query trực tiếp nhanh hơn 5 phút code

3. Nghĩ về failure trước khi nghĩ về happy path

Khi nhận một ticket, đừng bắt đầu bằng “làm sao để nó chạy đúng”. Hãy bắt đầu bằng “nó sẽ hỏng theo những cách nào”.

Ba câu hỏi nhanh:

  • Nếu request timeout giữa chừng, UI sẽ hiển thị gì?
  • Nếu user bấm Submit hai lần liên tiếp, có tạo ra hai record trùng không?
  • Nếu API trả về dữ liệu rỗng hoặc thiếu field, UI có crash không?

Ví dụ khi xây dựng tính năng import danh sách bệnh nhân từ Excel, happy path rất đơn giản: upload file → validate → lưu dữ liệu → thông báo thành công. Nhưng nếu file quá lớn, upload thất bại giữa chừng, có dòng dữ liệu không hợp lệ hoặc user upload lại cùng một file thì sao?

Nếu chỉ xử lý happy path, những trường hợp này thường chỉ được phát hiện sau khi đưa lên production. Nghĩ về failure ngay từ đầu giúp mình chủ động thiết kế validation, retry, duplicate checking và trạng thái lỗi thay vì chạy theo fix bug sau này.

❌ Chỉ xử lý flow: upload → save → success
✅ Thiết kế cả flow: upload → validate → save → success / retry / rollback / error

4. Gọi tên trade-off thành lời, đừng để nó ở dạng cảm tính

Thay vì nghĩ “cách này có vẻ tốt hơn”, hãy ép bản thân nói rõ mình đang đánh đổi điều gì.

Ví dụ khi xây dựng API lấy danh sách sản phẩm, có thể chọn query database trực tiếp mỗi lần request hoặc thêm Redis cache. Cách đầu tiên đơn giản hơn, dễ debug và ship nhanh hơn nhưng sẽ tạo nhiều tải lên database. Cách thứ hai phức tạp hơn và mất thêm thời gian triển khai, nhưng giảm đáng kể số lần truy vấn khi traffic tăng.

Khi trade-off được gọi tên rõ ràng — đơn giản vs. hiệu năng, tốc độ ship vs. khả năng scale, dễ bảo trì vs. độ phức tạp — quyết định kỹ thuật không còn dựa trên cảm tính. Sau này khi có người hỏi “tại sao lại làm theo cách này?”, team có thể giải thích dựa trên những đánh đổi đã được cân nhắc ngay từ đầu.

5. Viết design doc nửa trang cho bất kỳ feature nào chạm quá 2 module

Không cần template phức tạp. Chỉ cần 4 mục: vấn đề đang giải quyết, 2 phương án đã cân nhắc, phương án chọn và lý do, rủi ro đã biết.

Ví dụ, khi xây dựng tính năng đặt lịch khám trực tuyến, feature này có thể chạm tới nhiều module như bệnh nhân, lịch bác sĩ, đặt lịch và thông báo. Việc viết design doc trước giúp làm rõ ngay từ đầu: module nào chịu trách nhiệm kiểm tra lịch trống, module nào tạo booking, khi nào trừ slot và phase nào mới xử lý việc gửi thông báo hoặc đồng bộ với hệ thống khác.

Cách này giúp team thống nhất phạm vi và cách thiết kế trước khi code, tránh tình trạng đang làm mới phát hiện thêm dependency, phải đổi kiến trúc hoặc vừa code vừa thay đổi quyết định giữa chừng.

6. Review code người khác qua lăng kính hệ thống, không chỉ lăng kính cú pháp

Thay vì chỉ soi tên biến, format hay cách viết code, thử đặt thêm những câu hỏi ở cấp độ hệ thống:

  • Nếu function này được gọi 100 lần/giây thì database có chịu nổi không?
  • Nếu service bên ngoài bị timeout hoặc trả lỗi thì flow này xử lý thế nào?
  • Nếu hai request chạy đồng thời, có thể tạo dữ liệu trùng hoặc race condition không?
  • Module này có đang truy cập trực tiếp vào thứ mà nó không nên biết không?

Ví dụ, khi review một API lấy danh sách bệnh nhân, code có thể hoàn toàn đúng về mặt logic nhưng lại thực hiện thêm một query database cho mỗi bệnh nhân để lấy thông tin liên quan. Với 10 bệnh nhân thì không vấn đề, nhưng với 10.000 bệnh nhân, đây có thể trở thành bottleneck nghiêm trọng.

Review theo lăng kính hệ thống giúp team dần hình thành thói quen hỏi “code này sẽ hoạt động thế nào khi scale hoặc khi một dependency gặp sự cố?”, thay vì chỉ hỏi “code này có chạy đúng không?”.

7. Học cách nói “chưa cần” — tránh over-engineering ngược lại

Đây là tip dễ bị bỏ qua nhất. System design mindset không có nghĩa là mọi feature đều cần message queue, event sourcing, hay microservice. Với một app đang có vài nghìn user, thêm layer phức tạp “phòng khi sau này scale” thường chỉ tạo ra chi phí bảo trì không cần thiết ngay bây giờ. Câu hỏi đúng là: “có bằng chứng gì cho thấy mình cần cái này trong 6 tháng tới không, hay chỉ đang tưởng tượng ra rủi ro”.

❌ Thiết kế hệ thống queue phức tạp cho một tính năng gửi email 50 lượt/ngày
✅ Dùng cron job đơn giản, chỉ nâng cấp khi số liệu thực tế chứng minh cần thiết

Checklist áp dụng ngay hôm nay

  • Trước khi code: cái gì trong yêu cầu này sẽ đổi trong 3 tháng tới?
  • Trước khi viết function: module này sở hữu dữ liệu gì, ai được đọc, ai không được ghi?
  • Trước khi nghĩ happy path: nó sẽ chết kiểu gì trước?
  • Khi có 2 phương án: gọi tên trade-off thành câu, không để ở dạng cảm tính
  • Feature chạm >2 module: viết design doc nửa trang
  • Khi review code: hỏi thêm 1 câu về hệ thống, không chỉ về cú pháp
  • Trước khi thêm độ phức tạp: có bằng chứng thật cho thấy cần không?

Không cái tip nào ở trên đòi hỏi bạn phải có quyền quyết định kiến trúc. Chúng chỉ đòi hỏi bạn thay đổi thứ tự câu hỏi trong đầu — và điều đó bạn có thể bắt đầu ngay ticket tiếp theo.

Tóm lại những gì cần nhớ:

  • Mindset thể hiện qua câu hỏi bạn đặt, không qua title bạn có
  • 7 tip: đoán thay đổi, vẽ boundary, nghĩ failure trước, gọi tên trade-off, design doc ngắn, review theo lăng kính hệ thống, và biết nói “chưa cần”
  • Over-engineering cũng là một dạng thiếu mindset — không phải cứ phức tạp là “có tư duy hệ thống”

Bài cuối của series, mình sẽ nói về lý do sâu xa hơn: vì sao mindset này — chứ không phải kỹ năng code — mới là thứ khiến bạn khó bị AI hay đồng nghiệp khác thay thế trong 5 năm tới.

Áp dụng ngay: ticket tiếp theo bạn nhận, dành đúng 2 phút trước khi code để trả lời câu hỏi số 1 và số 3 ở trên. Không cần document, không cần họp — chỉ cần tự hỏi trong đầu.

Chúc anh em code vui! 🚀

Tags: #systemdesign #softwareengineering #careerdev #devworkflow

1 thought on “Áp Dụng System Design Mindset Vào Công Việc Hằng Ngày — Không Cần Chức Danh Architect”

  1. “Mình đâu phải Architect, đâu cần nghĩ mấy chuyện đó” — mình nghe câu này khá nhiều lần từ các bạn dev 1-3 năm kinh nghiệm. Vấn đề là: chờ đến khi có title rồi mới tập tư duy hệ thống thì hơi trễ. Title không tạo ra mindset. Mindset tạo ra title.

    Reply

Leave a Comment