Tư duy kiến trúc mở: Thiết kế hệ thống linh hoạt cho tương lai (tư duy EA)
7/19/2026 · 12p đọc
title: "Tư duy kiến trúc mở: Thiết kế hệ thống linh hoạt cho tương lai (tư duy EA)"
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: 33
audience: "BA, PO, EA & vai trò làm việc trực tiếp với khách hàng"
reading_time: "11 phút đọc"
tags:
- Enterprise Architecture
- Kiến trúc mở
- Vendor lock-in
- Khả năng mở rộng
- Thiết kế hệ thống
- EA mindset
Tư duy kiến trúc mở: Thiết kế hệ thống linh hoạt cho tương lai (tư duy EA)
Có một câu hỏi mà Enterprise Architect (EA — kiến trúc sư doanh nghiệp) nào cũng phải trả lời ít nhất một lần trong sự nghiệp: "Làm nhanh cho xong, hay làm chắc cho sau này?" Câu trả lời sai không giết chết dự án ngay lập tức — nó âm thầm giết chết dự án hai năm sau, khi khách hàng đã tăng trưởng gấp ba lần và hệ thống thì không nhúc nhích được. Bài này là về cách chọn đúng, và chọn đúng mà vẫn kịp deadline.
🎯 Kỹ thuật cốt lõi: Nguyên tắc thiết kế mở (Open Architecture Principles)
Tư duy kiến trúc mở không phải là "dùng open-source" hay "tránh mua sản phẩm của hãng lớn". Nó là một tập hợp nguyên tắc thiết kế giúp hệ thống có thể thay đổi mà không phải đập đi xây lại. Ba nguyên tắc cốt lõi, áp dụng được cho bất kỳ EA/kiến trúc sư nào, ở bất kỳ ngành nào:
1. Modular hóa theo ranh giới nghiệp vụ (bounded context), không theo ranh giới công nghệ.
Chia hệ thống thành các module độc lập, mỗi module sở hữu một miền nghiệp vụ rõ ràng (ví dụ: quản lý khách hàng, xử lý đơn hàng, thanh toán) và giao tiếp với nhau qua interface/API được định nghĩa tường minh — không phải qua việc đọc thẳng bảng dữ liệu của nhau. Nguyên tắc kiểm tra nhanh: nếu thay một module mà phải sửa code ở ba module khác, ranh giới đang sai chỗ.
2. Trừu tượng hóa (abstraction) tại các điểm tích hợp có rủi ro đổi nhà cung cấp.
Bất cứ chỗ nào hệ thống nói chuyện với một thành phần bên thứ ba dễ thay đổi trong tương lai — cổng thanh toán, dịch vụ gửi email/SMS, nhà cung cấp AI, hạ tầng cloud — hãy đặt một lớp interface (adapter/gateway) ở giữa. Code nghiệp vụ gọi vào interface đó, không gọi thẳng SDK của hãng. Khi cần đổi nhà cung cấp, chỉ viết lại adapter, không phải sửa toàn bộ codebase.
3. Ưu tiên khả năng mở rộng (extensibility) hơn tối ưu ngắn hạn, nhưng có giới hạn.
Đây là nguyên tắc dễ bị hiểu sai nhất. Nó KHÔNG có nghĩa là lúc nào cũng xây hệ thống "chuẩn bị cho 10 năm sau". Nó có nghĩa là: khi phải chọn giữa một giải pháp nhanh-nhưng-đóng-cứng và một giải pháp chậm-hơn-một-chút-nhưng-mở, và chi phí "mở" không vượt quá khoảng 20-30% effort tăng thêm, hãy chọn phương án mở. Nếu chi phí mở quá cao so với lợi ích chưa chắc chắn, EA giỏi vẫn chọn làm nhanh — nhưng phải ghi rõ đây là "technical debt có chủ đích" (deliberate debt) và có kế hoạch trả nợ.
Công cụ thực hành để cân bằng ba nguyên tắc này là một ma trận quyết định 2 trục: trục hoành là "Mức độ chắc chắn sẽ cần thay đổi/mở rộng" (thấp → cao), trục tung là "Chi phí làm mở ngay từ đầu" (thấp → cao). Bất cứ hạng mục nào rơi vào ô "chắc chắn cần đổi + chi phí mở thấp" thì bắt buộc phải làm mở ngay. Hạng mục rơi vào ô "khó chắc + chi phí mở cao" thì được phép làm tắt, miễn là gắn nhãn nợ kỹ thuật.
Bối cảnh (Situation)
(Tình huống dưới đây là minh hoạ tổng hợp từ nhiều dự án thực tế, không phải case cụ thể của một công ty nào.)
Anh T. là Enterprise Architect được thuê tư vấn cho một công ty thương mại điện tử trong ngành hàng tiêu dùng, đang trong giai đoạn tăng trưởng nóng — doanh thu tăng gấp đôi sau mỗi hai quý, đội ngũ kỹ thuật từ 8 người phình lên 30 người chỉ trong một năm. Ban lãnh đạo giao cho anh T. thiết kế lại kiến trúc hệ thống lõi: quản lý đơn hàng, tồn kho, và tích hợp với các sàn thương mại điện tử bên ngoài.
Sức ép thời gian cực lớn. CEO nói thẳng trong buổi kickoff: "Anh có 6 tuần để có bản MVP chạy được, vì tụi tôi sắp ký hợp đồng với một sàn TMĐT mới, không kịp là mất cơ hội." Đội dev nội bộ thì đã quen làm theo kiểu "xong việc trước, tính sau" — CTO của công ty, vốn xuất thân từ dân sales chuyển sang quản lý kỹ thuật, cũng nghiêng về hướng "cứ code cho chạy, sau này tính tiếp."
Vấn đề là anh T. nhìn vào roadmap kinh doanh 18 tháng tới và thấy rõ: công ty sẽ mở rộng sang ít nhất ba sàn TMĐT nữa, có kế hoạch tự vận hành kho riêng thay vì thuê ngoài, và đang đàm phán với hai nhà cung cấp dịch vụ thanh toán khác nhau để giảm phí. Nếu thiết kế hệ thống gắn cứng vào một sàn, một nhà kho, một cổng thanh toán ngay từ đầu, sáu tháng sau sẽ phải viết lại gần như toàn bộ.
Thách thức (Task)
Cái khó của anh T. không phải là kỹ thuật — anh biết cách thiết kế một hệ thống modular, mở. Cái khó là thuyết phục được một tổ chức đang chạy nước rút chấp nhận bỏ thêm thời gian cho một thứ họ không thấy giá trị ngay lập tức.
Nếu anh T. cứ áp đặt kiến trúc "chuẩn EA" mà không giải thích được bằng ngôn ngữ kinh doanh, anh sẽ bị gắn mác "lý thuyết, chậm, không hiểu sức ép thị trường" — và rất có thể bị gạt sang một bên, để đội dev tự làm theo cách cũ.
Ngược lại, nếu anh T. chiều theo áp lực và để đội dev code cứng thẳng vào API của sàn TMĐT đầu tiên, hard-code logic tính phí theo đúng cấu trúc của nhà cung cấp thanh toán hiện tại, và thiết kế module tồn kho giả định luôn luôn có một kho duy nhất do bên thứ ba vận hành — thì đúng 6 tháng sau, khi công ty cần thêm sàn thứ hai, đội kỹ thuật sẽ phải dừng toàn bộ tính năng mới để "refactor khẩn cấp", đúng lúc công ty cần tốc độ nhất. Đây là kịch bản kinh điển: nợ kỹ thuật không được nói ra sẽ đến hạn vào đúng thời điểm tệ nhất.
Thách thức kép: vừa phải giữ được deadline 6 tuần, vừa phải cài được "cửa mở" cho tương lai — mà không được phép biến nó thành một cuộc chiến giữa "EA lý thuyết" và "dev thực dụng."
Hành động (Action)
Anh T. không mở đầu bằng việc trình bày sơ đồ kiến trúc. Anh mở đầu bằng một buổi làm việc 90 phút với đúng ba người: CEO, CTO, và trưởng nhóm vận hành (Ops lead) — để lấy được bức tranh tăng trưởng thật, không phải bức tranh kỹ thuật.
Bước 1 — Lập bản đồ "điểm nóng thay đổi" (change hotspot mapping).
Anh T. hỏi từng người một câu hỏi giống nhau: "Trong 18 tháng tới, những gì chắc chắn sẽ đổi, và những gì gần như chắc chắn giữ nguyên?" Từ câu trả lời, anh liệt kê ra bảng:
| Thành phần | Khả năng thay đổi (18 tháng) | Ghi chú |
|---|---|---|
| Sàn TMĐT tích hợp | Rất cao — sẽ thêm 3 sàn mới | CEO xác nhận đã có kế hoạch |
| Nhà cung cấp thanh toán | Cao — đang đàm phán 2 đối tác | Để giảm phí giao dịch |
| Đơn vị vận hành kho | Cao — dự kiến tự vận hành sau 12 tháng | Đang thuê ngoài |
| Logic tính giá/khuyến mãi | Trung bình | Marketing muốn linh hoạt hơn |
| Quy trình xác thực người dùng | Thấp | Không có kế hoạch đổi |
Bảng này chính là dữ liệu đầu vào cho ma trận quyết định ở phần Kỹ thuật cốt lõi — nó biến câu chuyện "kiến trúc mở nghe hay nhưng trừu tượng" thành một danh sách cụ thể: cái nào cần trừu tượng hóa ngay, cái nào không cần.
Bước 2 — Áp ma trận quyết định để tách "phải làm mở ngay" khỏi "được phép làm tắt".
Với ba hạng mục đầu (sàn TMĐT, thanh toán, kho vận) — khả năng đổi cao, và chi phí thêm để làm interface trừu tượng chỉ khoảng 15-20% thời gian — anh T. xếp vào nhóm bắt buộc thiết kế mở. Với logic tính giá và xác thực người dùng, anh xếp vào nhóm "làm theo cách nhanh nhất trước, tối ưu sau", vì rủi ro thấp hơn hoặc chi phí làm mở ngay quá cao so với lợi ích chưa rõ ràng.
Bước 3 — Thiết kế modular theo ranh giới nghiệp vụ, không theo sàn cụ thể.
Thay vì để module "Đơn hàng" gọi thẳng API của sàn TMĐT hiện tại, anh T. thiết kế một lớp Integration Gateway đứng giữa: module nghiệp vụ chỉ biết gọi các hàm chung như createOrder(), syncInventory(), processPayment(); còn việc dịch các hàm này sang định dạng riêng của từng sàn, từng cổng thanh toán, được đóng gói trong các adapter riêng biệt, mỗi adapter một sàn/một đối tác. Khi công ty ký hợp đồng với sàn thứ hai, đội dev chỉ cần viết thêm một adapter mới, không đụng vào logic nghiệp vụ cốt lõi.
Tương tự với tồn kho: thay vì gắn cứng giả định "một kho, một API cố định", anh T. thiết kế module Tồn kho làm việc với một khái niệm trừu tượng là "Fulfillment Provider" (đơn vị thực hiện đơn hàng) — hiện tại chỉ có một provider (bên thuê ngoài), nhưng khi công ty tự vận hành kho, chỉ cần thêm một provider mới implement đúng interface, không phải viết lại toàn bộ luồng xử lý đơn hàng.
Bước 4 — Trình bày lại bằng ngôn ngữ rủi ro kinh doanh, không phải thuật ngữ kỹ thuật.
Khi trình bày lại với CEO và CTO, anh T. không nói "tôi sẽ áp dụng dependency inversion và adapter pattern." Anh nói: "Với thiết kế này, khi anh chị ký hợp đồng với sàn thứ hai, đội kỹ thuật cần khoảng 1-2 tuần để tích hợp thêm, không phải dừng sản phẩm 2 tháng để viết lại. Đổi lại, tuần đầu tiên chúng ta sẽ chậm hơn dự kiến khoảng 3-4 ngày so với cách làm tắt." Anh đưa ra con số cụ thể, đổi lấy sự đồng thuận, thay vì tranh luận đúng-sai về triết lý kiến trúc.
Bước 5 — Ghi nhận nợ kỹ thuật có chủ đích, công khai.
Với các phần anh T. chọn "làm tắt" (logic giá, xác thực), anh lập một mục riêng trong tài liệu kiến trúc gọi là "Nợ kỹ thuật đã chấp thuận" (Accepted Technical Debt), ghi rõ lý do, điều kiện để phải xử lý (ví dụ: "khi có trên 2 chương trình khuyến mãi chạy song song, phải refactor logic giá"), và người chịu trách nhiệm theo dõi. Việc này giúp nợ kỹ thuật không biến mất trong im lặng rồi trở thành khủng hoảng bất ngờ.
Kết quả (Result)
Đội dev hoàn thành MVP đúng hạn 6 tuần, chậm hơn kế hoạch ban đầu khoảng 4 ngày so với phương án làm tắt hoàn toàn — con số này anh T. đã báo trước nên không ai bất ngờ. Công ty ký được hợp đồng với sàn TMĐT đầu tiên đúng thời hạn.
Bốn tháng sau, khi công ty chuẩn bị tích hợp sàn thứ hai, đội dev chỉ mất khoảng 10 ngày để viết adapter mới, thay vì phải dừng lại refactor như kịch bản đáng lo ban đầu — đúng như anh T. đã cam kết. Tám tháng sau, khi công ty bắt đầu tự vận hành một phần kho, module Fulfillment Provider mới cũng chỉ cần bổ sung, không cần đập đi làm lại.
Điều không hoàn hảo: mục "nợ kỹ thuật có chủ đích" về logic tính giá, dù đã ghi rõ điều kiện kích hoạt, vẫn bị đội marketing vượt qua nhanh hơn dự kiến — họ chạy ba chương trình khuyến mãi chồng lấn chỉ sau ba tháng thay vì dự kiến 8-10 tháng, buộc đội kỹ thuật phải refactor gấp phần này ngoài kế hoạch. Đây là bài học cho chính anh T.: dự báo tốc độ thay đổi từ phía kinh doanh luôn khó hơn dự báo thay đổi kỹ thuật, và cần rà soát lại "bản đồ điểm nóng thay đổi" định kỳ mỗi quý, không chỉ làm một lần rồi để đó.
📋 Áp dụng ngay
- Trước khi thiết kế bất kỳ hệ thống nào, ngồi lại 60-90 phút với người ra quyết định kinh doanh để lập "bản đồ điểm nóng thay đổi" — hỏi thẳng cái gì chắc chắn đổi trong 12-18 tháng tới.
- Với mọi điểm tích hợp bên thứ ba (thanh toán, gửi tin, AI, cloud), luôn đặt một lớp interface/adapter ở giữa — đừng để code nghiệp vụ gọi thẳng SDK của hãng.
- Dùng ma trận 2 trục (khả năng thay đổi × chi phí làm mở) để quyết định hạng mục nào bắt buộc thiết kế mở, hạng mục nào được phép làm tắt.
- Khi chọn làm tắt, ghi nhận công khai thành "nợ kỹ thuật có chủ đích" kèm điều kiện kích hoạt refactor và người theo dõi — đừng để nó âm thầm biến mất.
- Trình bày quyết định kiến trúc bằng con số thời gian/chi phí cụ thể cho ban lãnh đạo, không dùng thuật ngữ pattern kỹ thuật.
💡 Bài học đúc rút (Key Takeaway): Kiến trúc mở không phải là làm mọi thứ "chuẩn" và "chậm hơn" — nó là biết chính xác chỗ nào đáng bỏ thêm 15-20% effort để mua một cánh cửa thoát hiểm cho tương lai, và chỗ nào được phép khoá cứng vì rủi ro thực sự thấp. EA giỏi không phải người luôn chọn phương án mở, mà là người biết rành mạch lúc nào nên mở, lúc nào nên tắt, và dám ghi rõ ra giấy quyết định đó thay vì để nó trôi trong im lặng.
🔗 Kỹ năng liên quan
- Dự báo rủi ro — kỹ thuật nhận diện sớm các điểm mù trước khi chúng thành khủng hoảng, nền tảng để lập bản đồ điểm nóng thay đổi.
- Visualizing Complex Systems (Cho EA) — cách trực quan hoá kiến trúc modular để thuyết phục các bên liên quan phi kỹ thuật.
- Tư duy TCO (Total Cost of Ownership) — góc nhìn chi phí dài hạn bổ sung cho quyết định "mở hay tắt" trong bài này.
Bài trước: Dự báo rủi ro · Bài tiếp theo: Cách trình bày phương án (Pitching)