Thứ Sáu, 29 tháng 6, 2012

Cohesion và Coupling


Khi học môn Công nghệ phần mềm, cohesion và coupling là hai khái niệm mà HM đôi khi cảm thấy hơi lẫn lộn. Hi vọng bài viết này sẽ phần nào giúp những người cùng cảnh ngộ phân biệt chúng rõ ràng hơn.
Trước hết, hãy nói về nguyên tắc chung khi thiết kế chương trình:
  1. Giữ những thứ phải thay đổi cùng nhau ở thật gần nhau. Chẳng hạn khi thay đổi về thiết kế ở class A luôn kéo theo thay đổi ở B, thì nên cho A và B vào cùng một module.
  2. Cho phép những thứ không liên quan thay đổi một cách độc lập với nhau (nói cho có vẻ “chuyên ngành” là orthogonal). Ví dụ không có lí do gì để sửa đổi class Person khi class Money bị sửa đổi.
Từ hai nguyên tắc này có thể đẻ ra cả tá nguyên tắc và khái niệm cụ thể hơn, mà trong đó có cohesion và coupling. Tuy nhiên, nếu nắm vững hai nguyên tắc trên thì trong trường hợp không biết về các khái niệm khác, bạn vẫn có thể nhận ra những bất thường trong thiết kế.
Vậy cohesion là gì? Khi nói đến cohesion chúng ta nghĩ đến nhiệm vụ của từng module. Nhiệm vụ của từng module càng rõ ràng và tách biệt thì cohesion càng cao (high cohesion), và đó là mục tiêu cần đạt tới khi thiết kế. Giải thích bằng code có lẽ sẽ không rõ ràng bằng bài viết này:
Tại kỳ họp Quốc hội thứ năm, khi thảo luận về quản lý chất lượng vệ sinh an toàn thực phẩm có vị đại biểu Quốc hội đã ví việc có tới 5 bộ chịu trách nhiệm chính như vậy cũng giống như “nhiều sãi không ai đóng cửa chùa”.
Bởi thế, làm rõ trách nhiệm của từng cơ quan quản lý Nhà nước về an toàn thực phẩm là một yêu cầu được nhấn mạnh khi xây dựng dự Luật An toàn thực phẩm.
Thực ra không có một phương pháp tuyệt đối để xác định những nhiệm vụ nào thì được coi là liên quan và nên được xếp vào cũng một module, hay những nhiệm vụ nào là không phù hợp với một module nào đó. Tuy nhiên, có một cách rất hữu dụng, là kiểm tra tên của một class hay method. Nếu bạn không thể kiếm một cái tên phù hợp cho class, bạn nên kiểm tra xem nhiệm vụ của module tương ứng đã được định nghĩa rõ ràng chưa. Cũng vậy, nếu tên của một method có từ and hoặc chứa hai hành động trở lên, thì bạn nên xem xét phân tách method thành nhiều method nhỏ hơn. Về các lời khuyên liên quan đến cách đặt tên, xem thêm Code complete.
Tiếp theo là coupling. Coupling là khái niệm chỉ độ phụ thuộc giữa các module với nhau khi thực hiện một chức năng nào đó. Cũng như cohesion, coupling được chia làm nhiều cấp độ, và một thiết kế tốt sẽ cho coupling thấp (loose coupling). Thế nào là phụ thuộc? Đó là khi một module khi hoạt động phải hiểu biết về chức năng và cách hoạt động của các module khác. Chẳng hạn, khi một class dùng chung một vùng nhớ (một object chẳng hạn) với class khác, thì class này phải hiểu rõ class kia sẽ làm gì với vùng nhớ chung đó, và vậy là có coupling giữa hai class. Có rất nhiều dạng coupling, có dạng chấp nhận được, có dạng nên hạn chế, bạn có thể xem thêm trong Code complete.
Lí do phải giảm coupling là vì nếu nhiều module couple chặt với nhau, thì khi bạn thiết kế lại một module, bạn sẽ phải kiểm tra tất cả các module còn lại, và coupling càng chặt thì khả năng các module còn lại này bị thay đổi càng cao. Ngoài ra, có một số dạng coupling ngầm tương đối khó nhận ra, điều này sẽ làm cho việc thay đổi càng khó khăn hơn. Bạn có thể liên hệ với thủ tục hành chính. Nếu người dân phải đi qua nhiều bước thủ tục thì khi các bước này bị thay đổi, người ta phải tuyên truyền lại cho nhiều chục triệu người dân lẫn nhân viên hành chính. Nếu các bước thủ tục này được encapsulate lại thành một bước duy nhất (“một cửa”) thì người ta chỉ phải đến, đưa hồ sơ (“input”) và lấy kết quả (“output”). Thay đổi về thủ tục bây giờ chỉ đòi hỏi đào tạo lại các nhân viên bên trong.
Bạn có thể thấy cohesion và coupling phần nào phản ánh hai nguyên tắc ban đầu.

Không có nhận xét nào: