Coupling – sự phụ thuộc giữa các module

Coupling nói một cách đơn giản nó là sự phụ thuộc lần nhau giữa các modules (có thể hiểu là class, thành phần của phần mềm), là tính liên kết giữa các modules. Thiết kế code tốt thì phải theo hướng loose coupling tức là sự liên kết giữa các class, các thành phần trong phần mềm càng ít chặt chẽ càng tốt. Bởi vì nếu các thành phần quá phụ thuộc lẫn nhau, khi chúng ta thay đổi 1 thành phần sẽ ảnh hưởng tới rất nhiều thành phần liên quan khác.

1.1 Content coupling

Đây là vi pham couling ở mức cao nhất được định nghĩa là khi mà một component có thể truy cập trực tiếp vào hoạt động bên trong của một component khác ví dụ như trực tiếp truy xuất data, thay đổi data của component. Hiểu đơn giản rằng chúng ta có 2 class A và B trong đó một đối tượng class A có một trường dữ liệu có giá trị là 1 đối tượng của class B. Khi đó nếu như bên trong object của class A có thể truy cập thông tin của object class B một cách trực tiếp thông qua B.field_name thì đó chính là vi phạm về content coupling. Để tránh điều này thì đối tượng lớp A không được trực tiếp truy cập vào nội dung của đối tượng lớp B mà phải thông qua method của đối tượng lớp B bằng cách set private cho field data và sử dụng các getter, setter method để truy xuất dữ liệu. Ví dụ cho tính nghiêm trọng của content coupling đó là Balance cho tài khoản ngân hàng, chúng ta không get, set trực tiếp số tiền được mà phải thay đổi bằng cách gọi các hàm trừ tiền.

1.2 Common coupling

image.pngCommon coupling xảy ra khi mà 2 hay nhiều module cùng đọc và thay đổi 1 dữ liệu dùng chung. Đây cũng là một thiết kế tệ bởi vì nó gây ra sự không rõ ràng về vai trò của dữ liệu, code sẽ khó đọc, khó có thể xác định những thành phần code nào liên quan và ảnh hưởng đến dữ liệu dùng chung. Do đó giảm khả năng bảo trì hay tái sự dụng component. Common coupling thường xảy ra ở các ngôn ngữ lập trình hướng cấu trúc như C bởi việc sử dụng data global là thường xuyên.

1.3 Control coupling

Xảy ra khi mà tham số truyền vào cho module sẽ quyết định luồng xử lý của module theo những cách khác nhau. Điều này cũng rất thường gặp khi chúng ta truyền tham số vào hàm và tham số đó có thể chia thành nhiều nhóm dữ liệu. Do đó bên trong hàm chúng ta sẽ dùng nhiều if else để check tham số truyền vào. Và hãy hình dung xem, với mỗi loại tham số truyền vào thì function đó thực ra chỉ chạy 1 phần code trong 1 block if else thoã mãn điều kiện và đương nhiên rằng những phần code còn lại là không được chạy. Ví dụ như function updateCustomer(int type, Customer customer) với type có thể là các giá trị CREATE, EDIT, DELETE. nhưng customer chỉ sử dụng cho EDIT, với type là DELETE thì chỉ cần truyền id vào thay vì customer, đối với CREATE thì không cần sử dụng gì đến customer.

Còn rất nhiều tình huống thực tế khác có thể xảy ra có thể do chúng ta muốn xử lý nhanh vấn đề nhưng có thể dễ dàng thấy được code thiết kế như vậy sẽ khó đọc phụ thuộc vào số lượng kiểu của tham số truyền vào, nếu như nhiều thì code sẽ có if else rất nhiều level và giả sử xử lý logic là phức tạp, đó sẽ là cực hình khi mở rộng hay thay đổi tính năng.

1.4 Stamp coupling

Đến đây thì vi phạm coupling đã không còn ở mức high nữa mà đã có thể chấp nhận được. Stamp coupling xảy ra khi tham số truyền vào cho module là thừa, việc xử lý có thể chỉ cần một vài trường dữ liệu của object nhưng chúng ta truyền nguyên object vào. Ví dụ như function printInvoice() và chúng ta truyền customer trong khi chỉ thông tin tên và địa chỉ khách hàng vậy thì những thông tin khác nằm trong customer là không cần thiết.

1.5 Data coupling

Là coupling ở mức thấp nhất khi mà các modules tương tác với nhau chỉ thông qua tham số truyền vào. Điều này là không thể tránh khỏi do vậy thiết kế này là được cho là mục tiêu hướng đến. Data coupling và stamp coupling đều được xác định bởi tham số truyền vào nhưng khác ở chỗ data coupling không dư thừa dữ liệu tham số truyền vào, tất cả tham số truyền vào đều được sử dụng để xử lý.

Related Posts