Apr 28, 2013

Phụ thuộc vòng

Bài viết đang được hoàn thiện

Phụ thuộc vòng - một cách dịch đầy thô thiển. Tên chính xác của nó "Circular Dependency". Nghe khá rờm rà. Từ giờ trở đi gọi là CDepend cho gọn. Wiki có hẳn 1 bài về nó: link đây. Đại để có thể hiểu theo ngôn ngữ C++ như sau: File header A dùng để khai báo lớp A, file header B dùng để khai báo lớp B. Trong lớp A có 1 attribute (thuộc tính) là thể hiện của B, và trong lớp B có một thuộc tính là thể hiện của A. Và như vậy, theo lẽ thông thường, Trong file header A sẽ có dòng #include"B.h" và trong file header B có dòng #include"A.h". Mọi sự rắc rối rồi.

Hậu quả:

  • Phát sinh những vấn đề không mong muốn trong quá trình thiết kế lớp. Như ví dụ nêu trên chắc chắn là sẽ chẳng thể cài đặt với thiết kế và giải pháp đó
  • Gây rò rỉ vùng nhớ (memory leak). Vì sao ư? Đối với các ngôn ngữ không có hỗ trợ việc tự dọn rác (automatic memory management), việc tự thiết kế các phương thức hủy (destructor) hay giải phóng vùng nhớ đối với các lớp phụ thuộc lẫn nhau như thế này rất khó chịu. Nếu "lỡ tay" giải phóng hết các thuộc tính trong A, tức là giải phóng luôn có bé thể hiện B trong đó. Mà bé ý vẫn còn đang sống nhăn răng, vẫn chưa muốn bị hủy thì coi như tách. Cài đặt fail và số quá nhọ. Dĩ nhiên, điều "may mắn" là compiler không bao giờ coi đó là syntax error để thông báo ngay từ đầu cả.
  • Gây hiệu ứng domino: một tác động nhỏ lên lớp này ảnh hưởng đến toàn bộ các lớp khác. Theo nguyên tắc thiết kế, các lớp phải độc lập khi sửa chữa. Tức thay đổi của lớp này không ảnh hưởng đến lớp kia.

Một số điểm thuận lợi:

Không phải cái gì xấu, hại thì xấu hoàn toàn. Cái gì nó cũng có 2 mặt của 1 vấn đề. CDepend cũng có một số điểm tích cực

  1. Có những thiết kế bắt buộc phải dính tới CDepend. Và như vậy buộc ta phải cài đặt nó. Ví dụ: danh sách liên kết, đồ thị ...

Giải quyết

  • Có những tool chuyên trị cái này: JDepend (cho Java), Code Analysis Plugin (cho Java).
  • Sử dụng mẫu thiết kế Observer, Visitor, Factory... blah blah

Một số vấn đề trong C++

Phần này sẽ nêu 1 số ví dụ thường gặp, thường dính khi lập trình trên C++

Tài liệu tham khảo:

Hầu hết những gì chém gió phía trên đều được trích lược và tran sờ lai (translate) sang Tiếng Việt. Những nguồn này khá bổ ích

  1. Avoiding Circular Dependencies of header files
  2. Wikipedia
  3. Một bài viết hữu ích trên stackoverflow
  4. Một bài tập nho nhỏ
  5. Có hẳn 1 mục trong stackoverflow