Appearance
Tư duy kiến trúc
Khi muốn thay đổi một thư viện tính toán hay một ngưỡng cấu hình nhỏ, thành viên mới thường phát hiện bản thân phải sửa đổi hàng loạt tệp tin rải rác khắp hệ thống và vô tình làm hỏng nhiều chức năng hoạt động bình thường khác. Làm thế nào để thiết kế một hệ thống linh hoạt, nơi mỗi thay đổi nhỏ được cô lập hoàn toàn và không gây ảnh hưởng lan truyền đến các phần khác?
Bài viết này trình bày các nguyên tắc kiến trúc phần mềm cốt lõi: tách biệt lõi bất biến khỏi các phần dễ thay đổi, giao tiếp qua giao diện hợp đồng thống nhất, phân rã các cấu phần độc lập, và duy trì phụ thuộc một chiều hướng về lõi.
1. Bảng thuật ngữ cục bộ
| Thuật ngữ | Tên tiếng Anh | Dịch nghĩa & Giải thích |
|---|---|---|
API | Application Programming Interface | Giao diện lập trình ứng dụng. |
DAG | Directed Acyclic Graph | Đồ thị có hướng không chu trình. |
2. Các khái niệm cốt lõi
2.1 Tách lõi bất biến khỏi phần dễ thay đổi
- ⚙️ Cơ chế: Nhận diện và tách biệt các logic kinh doanh cốt lõi, ít biến động (như định dạng dữ liệu đầu vào hoặc thước đo cơ bản) để làm nền tảng (lõi), đồng thời đóng gói các thành phần dễ biến động (như thuật toán mô hình, các ngưỡng tham số) đằng sau các giao diện lập trình (
API) độc lập. - 🔍 Cách nhận diện: Cấu trúc mã nguồn chia thành các thư mục lõi ổn định (ví dụ:
core/,domain/) và các module ứng dụng/thử nghiệm ở rìa. - 💡 Ý nghĩa: Đảm bảo hệ thống có một nền tảng vững chắc, giảm thiểu tối đa rủi ro hỏng hóc khi thay đổi các tính năng ở rìa.
- ⚠️ Bẫy: Cho phép các quyết định công nghệ tạm thời (như chọn một thư viện cụ thể) xâm nhập và dính chặt vào logic cốt lõi của hệ thống.
2.2 Giao diện hợp đồng thống nhất
- ⚙️ Cơ chế: Thiết lập một cầu nối trung gian duy nhất để làm điểm giao tiếp chung giữa các module sản xuất dữ liệu và tiêu thụ dữ liệu, thay vì cho phép các module gọi trực tiếp chéo nhau.
- 🔍 Cách nhận diện: Định nghĩa các lớp dữ liệu trung gian (data classes hoặc schemas) làm chuẩn giao tiếp chung.
- 💡 Ý nghĩa: Giảm số lượng mối liên kết trong hệ thống từ tích số (ở mạng lưới chéo trực tiếp) xuống tổng số các module, giúp việc cắm hoặc rút một module diễn ra dễ dàng mà không ảnh hưởng đến phần còn lại.
- ⚠️ Bẫy: Sửa đổi cấu trúc hợp đồng chung một cách tùy tiện mà không có sự đồng thuận từ tất cả các bên tham gia sử dụng hợp đồng đó.
2.3 Phân rã thành phần độc lập và phụ thuộc một chiều
- ⚙️ Cơ chế: Chia nhỏ hệ thống thành các module đơn trách nhiệm (mỗi module được mô tả bằng một câu đơn không chứa từ "và"), sắp xếp theo tầng và chỉ cho phép tầng trên phụ thuộc vào tầng dưới, tuyệt đối không có phụ thuộc vòng (
DAGsạch). - 🔍 Cách nhận diện: Biểu diễn cấu trúc gọi hàm dưới dạng đồ thị có hướng không chu trình, các module được đặt tên rõ ràng theo vai trò kỹ thuật hoặc nghiệp vụ.
- 💡 Ý nghĩa: Giúp dễ dàng kiểm thử độc lập từng cấu phần và tái cấu trúc hệ thống một cách an toàn.
- ⚠️ Bẫy: Để tầng dưới chứa các thông tin hoặc import ngược từ tầng trên, tạo ra mối ràng buộc chặt chẽ khiến không thể biên dịch hoặc chạy độc lập.
2.4 Điểm mở rộng và gỡ bỏ
- ⚙️ Cơ chế: Thiết kế các cơ chế cấu hình (configuration-driven) hoặc đăng ký plugin để thêm mới tính năng mà không cần sửa đổi mã nguồn cốt lõi, đồng thời cô lập các tính năng thử nghiệm để có thể xóa bỏ hoàn toàn khi cần.
- 🔍 Cách nhận diện: Sử dụng các file cấu hình YAML/JSON để bật tắt tính năng, cấu trúc code thử nghiệm nằm riêng trong các tệp độc lập dễ dàng xóa đi.
- 💡 Ý nghĩa: Tăng tốc độ phát triển bằng cách cho phép nhiều lập trình viên cùng mở rộng hệ thống song song mà không xung đột mã nguồn.
- ⚠️ Bẫy: Gộp chung code thử nghiệm ngắn hạn vào các hàm xử lý chính thống, tạo ra "nợ kỹ thuật" tích tụ khó gỡ bỏ về sau.
✅ Tự kiểm nhanh
- Đổi một chi tiết nhỏ mà hỏng năm chỗ khác. Kiến trúc đã sai ở đâu?
Đáp án
Chưa tách phần dễ đổi và giấu sau một giao diện riêng, và chưa đặt một giao diện hợp đồng thống nhất để các phần nói chuyện qua đó. Vì thế một thay đổi lan ra nhiều module thay vì gói gọn một chỗ.
- Vì sao nối các thành phần qua một cầu nối chung rẻ hơn nối chéo trực tiếp?
Đáp án
Nối chéo trực tiếp làm số mối nối bùng nổ theo tích số bên sản xuất và bên tiêu thụ; nối qua một cầu nối chung thì số mối nối chỉ còn theo tổng. Ít mối nối hơn nghĩa là đổi một bên không kéo theo sửa nhiều bên khác.