Che giấu thông tin (Information Hiding)
1. Tổng quan
A. Định nghĩa
Nguyên lý thiết kế phần mềm che giấu chi tiết cài đặt và dữ liệu bên trong module khỏi bên ngoài, chỉ công khai giao diện được định nghĩa rõ ràng để giảm độ ghép nối (coupling) giữa các module. D.L. Parnas đề xuất nguyên lý này trong bài báo năm 1972.
Điểm xuất phát của che giấu thông tin là câu hỏi "lấy cái gì làm ranh giới module". Parnas cho rằng nên chia hệ thống không theo trình tự xử lý (lưu đồ) mà theo các quyết định có khả năng thay đổi cao (bí mật thiết kế). Nếu nhốt những phần dễ thay đổi (cách biểu diễn cấu trúc dữ liệu, thuật toán, quy cách bên ngoài...) vào trong một module và che giấu quyết định đó như một "bí mật", thì dù bí mật đó thay đổi, các module khác cũng không bị ảnh hưởng. Tức là che giấu thông tin không chỉ là một kỹ thuật hạn chế truy cập đơn thuần mà là chiến lược phân rã module nhằm cục bộ hóa tác động lan truyền của thay đổi.
B. Sự cần thiết
Tổng chi phí của phần mềm phát sinh ở khâu thay đổi và bảo trì lớn hơn ở khâu phát triển, và nếu các module biết và phụ thuộc vào phần bên trong của nhau thì sẽ phát sinh hiệu ứng lan truyền (Ripple Effect), trong đó một chỗ sửa đổi làm hỏng dây chuyền các chỗ khác. Che giấu thông tin khiến mỗi module chỉ tương tác qua giao diện công khai, nhờ đó dù cài đặt bên trong thay đổi, chỉ cần giữ nguyên giao diện thì không phải động đến các module khác. Nhờ vậy, tính độc lập và khả năng bảo trì của module được nâng cao, và bằng cách che đi phần bên trong phức tạp, trừu tượng hóa được hiện thực hóa.
2. Cấu trúc khái niệm
flowchart LR
C[Module gọi] -->|Giao diện công khai| I[Giao diện<br/>công khai]
I --> M[Bên trong module<br/>cấu trúc dữ liệu·thuật toán·trạng thái<br/>được che giấu]
Cốt lõi là tách giao diện và cài đặt thành hợp đồng và thực thi. Bên gọi chỉ cần biết module đó bảo đảm cái gì (What) (lời hứa của giao diện), còn việc nó đạt được điều đó như thế nào (How) (cấu trúc dữ liệu, thuật toán bên trong) thì không cần biết và cũng không nên biết. Ví dụ, nếu chỉ công khai hợp đồng "trả về danh sách đã sắp xếp", thì bên trong dùng quicksort hay merge sort cũng không liên quan tới bên gọi. Chỉ khi bên gọi không biết cài đặt bên trong thì mới có thể tự do thay đổi cài đặt đó, nên chính việc "không biết" lại trở thành nguồn gốc của tính linh hoạt.
3. Quan hệ giữa che giấu thông tin và đóng gói
Hai khái niệm thường bị nhầm lẫn nhưng ở các tầng khác nhau. Che giấu thông tin là nguyên lý thiết kế (mục đích) xác định "che giấu cái gì và tại sao", còn đóng gói (encapsulation) là kỹ thuật cài đặt (phương tiện) gói dữ liệu và các phương thức xử lý dữ liệu đó thành một khối. Bằng việc gói dữ liệu vào trong đối tượng bằng đóng gói và hạn chế truy cập bằng private, mục đích che giấu thông tin mới được hiện thực trên thực tế. Tức là có thể bàn về che giấu mà không cần đóng gói (quy ước giao diện module...), nhưng trong lập trình hướng đối tượng, đóng gói là phương tiện tiêu biểu để đạt được che giấu. Hiểu theo quan hệ mục đích và phương tiện thì sự khác biệt giữa hai khái niệm trở nên rõ ràng.
| Phân loại | Che giấu thông tin | Đóng gói |
|---|---|---|
| Khái niệm | Nguyên lý thiết kế che giấu chi tiết cài đặt (mục đích) | Kỹ thuật gói dữ liệu+phương thức (phương tiện) |
| Trọng tâm | Hạn chế truy cập·che giấu bí mật | Gắn kết (gói lại) |
| Quan hệ | Được hiện thực qua đóng gói | Phương tiện hỗ trợ che giấu thông tin |
| Ví dụ cài đặt | private, quy ước giao diện module |
Lớp, đối tượng |
4. Kỹ thuật cài đặt và các nguyên tắc liên quan
Che giấu thông tin được cụ thể hóa qua các kỹ thuật và nguyên tắc ở nhiều tầng. Ở cấp ngôn ngữ, bộ điều khiển truy cập (private·protected) che phần bên trong, còn giao diện/lớp trừu tượng chỉ phơi bày hợp đồng và tách cài đặt. Về nguyên tắc thiết kế, định luật Demeter — không để đối tượng đào sâu vào bên trong đối tượng lạ, nguyên tắc đóng-mở (OCP) — mở cho mở rộng và đóng cho sửa đổi, và đảo ngược phụ thuộc (DIP) — phụ thuộc vào trừu tượng thay vì cài đặt cụ thể, đều gắn liền với che giấu. Rốt cuộc, chúng cùng chia sẻ một định hướng: "che giấu các chi tiết có thể thay đổi đằng sau trừu tượng".
| Phân loại | Nội dung |
|---|---|
| Bộ điều khiển truy cập | Che giấu phần bên trong bằng private·protected |
| Giao diện/lớp trừu tượng | Chỉ phơi bày hợp đồng, tách cài đặt |
| Nguyên tắc liên quan | Đóng gói·trừu tượng hóa, định luật Demeter, OCP, DIP |
5. Ưu điểm và hiệu quả
Các hiệu quả mà che giấu thông tin mang lại liên kết với nhau. Vì các module chỉ giao tiếp qua giao diện nên độ ghép nối giảm, và vì các chức năng, dữ liệu liên quan tập trung trong một module nên độ kết dính (cohesion) tăng. Độ ghép nối thấp và độ kết dính cao cho phép sửa đổi, thay thế một module một cách độc lập nên khả năng bảo trì tăng, và giao diện đã được kiểm chứng có thể được tái sử dụng ở nhiều nơi. Ngoài ra, do ngăn bên ngoài trực tiếp động vào dữ liệu bên trong, còn đạt được hiệu quả toàn vẹn·bảo mật, ngăn chặn thay đổi trạng thái sai. Tức là một nguyên lý cải thiện đồng thời nhiều chỉ số chất lượng.
| Hiệu quả | Giải thích |
|---|---|
| Độ ghép nối thấp | Giảm phụ thuộc giữa các module → sửa đổi độc lập |
| Độ kết dính cao | Chức năng liên quan tập trung bên trong module |
| Khả năng bảo trì | Khi giữ nguyên giao diện, thay đổi bên trong không gây ảnh hưởng |
| Tái sử dụng·bảo mật | Tái sử dụng giao diện đã kiểm chứng, bảo vệ dữ liệu bên trong |
6. Lưu ý và hàm ý
- Nguyên lý xuyên suốt mọi quy mô: Từ
privatecủa lớp đến ranh giới dịch vụ trong MSA và thiết kế API mở, cùng một nguyên lý "che giấu cài đặt, chỉ phơi bày hợp đồng" xuyên suốt. Việc mỗi dịch vụ trong MSA không chia sẻ trực tiếp DB mà chỉ giao tiếp qua API cũng là sự mở rộng của che giấu thông tin. - Tính ổn định của giao diện chính là tính linh hoạt: Nếu giao diện thay đổi thường xuyên, lợi ích của che giấu sẽ mất đi, nên việc ổn định hợp đồng trước bằng thiết kế ưu tiên giao diện (API-first) là rất quan trọng.
- Chi phí của che giấu quá mức: Quá nhiều tầng trừu tượng gây overhead hiệu năng và khó khăn trong gỡ lỗi, truy vết. Cần phân biệt "bí mật có thể thay đổi" đáng để che giấu với những thứ không đáng, để xác định mức trừu tượng phù hợp.
Tóm tắt một câu: Che giấu thông tin là nguyên lý thiết kế che giấu các chi tiết cài đặt có thể thay đổi và chỉ công khai giao diện để cục bộ hóa tác động lan truyền của thay đổi; mục đích là che giấu được hiện thực bằng phương tiện là đóng gói, và qua việc giảm độ ghép nối, nâng cao khả năng bảo trì, nó trở thành nền tảng của thiết kế MSA và API.