Thiết kế xây dựng phần mềm – Cohesion

I. Khái niệm

Trong thiết kế xây dựng phần mềm, cohesion được định nghĩa là tính kết dính trong một module, điều này có nghĩa là các sub-module trong một module được sinh ra và sử dụng để cùng hướng đến một module và chỉ thực hiện một single task nào đó.

II. Cohesion

Với lập trình hướng thủ tục (các ngôn ngữ C/C++, …) ta sẽ xét trên yếu tố

  • Procedure, Function: Xét bên trong một function (có thể là khối lệnh, …)

Với lập trình hướng đối tượng (java, …) ta sẽ xét trên 3 yếu tố

  • Method: Xét bên trong một method, các khối lệnh bên trong method đó
  • Class: Xét bên trong một lớp (attributes & methods)
  • Subsystem: Xét các class hoặc interface

Trái ngược với coupling, trong một module, cohesion càng cao thì đồng nghĩa đó là một bản thiết kế tốt.

Ở trong phạm vi của bài viết này, ta sẽ xét ở mức độ class.

1. Coincidental Cohesion (Worst cohesion)

  • Các thành phần (element) trong một component không liên quan đến nhau, vì một lý do nào đó mà chúng được đặt trong cùng component đó.
  • Điều này có thể xảy ra từ các lập trình viên hoặc vì một lý do ngoại lệ nào đó

Như ví dụ trên, trong hàm main có các khối lệnh:

  • processing args
  • opening stream & read data
  • processing data
  • closing stream & clean data

Như vậy, khối lệnh đầu tiên và 3 khối lệnh còn lại không liên quan đến nhau nhưng vì một lý do nào đó mà chúng lại được đặt trong hàm main. Đoạn mã nguồn này đã vi phạm Coincidental cohesion một cách nghiêm trọng.

Với đoạn mã nguồn trên, ta có thể có cách cải thiện như dưới đây

2. Temporal Cohesion (Not good cohesion)

  • Khái niệm: Các element được đặt trong component chỉ vì cùng một loại.

Như ví dụ trên, một class AuthService có rất nhiều method với rất nhiều tính năng khác nhau (login bằng google, login bằng email, …). Các method này được đặt cùng một class chỉ vì cùng loại (đều là auth), tuy nhiên, nội bộ login từng method này không liên quan đến nhau. Rõ ràng việc xử lý login bằng google và login bằng facebook nó sẽ có những cơ chế khác nhau.

Để cải thiện đoạn mã nguồn này, ta có thể sử dụng các interface và ứng dụng các tính chất của OOP

3. Temporal cohesion (not good cohesiong)

  • Khái niệm: Các element được nhóm với nhau chỉ vì liên quan với nhau đến thời gian thực hiện

4. Procedural cohesion

  • Khái niệm: Các element được đặt chung với nhau chỉ vì thực hiện theo một thứ tự nhất định

Ở ví dụ trên, với method calculateCPA đang phải thực hiện nhiều hơn một nhiệm vụ, và nội trong method này các luồng xử lý đang phải thực hiện một cách thứ tự. Để tính được điểm CPA thì method này sẽ phải tính điểm GPA, lưu GPA vào database rồi lúc này mới tính được điểm CPA và lưu vào database.

Để tối ưu đoạn mã nguồn này chúng ta có thể tách thành 2 method khác nhau

5. Communicational cohesion

  • Khái niệm: Các element được đặt với nhau vì chúng làm việc thông qua dữ liệu

Đây là một bản thiết kế tốt, thể hiện tốt được tính đóng gói hay tính mở rộng trong các nguyên tắc lập trình.

6. Functional cohesion – best cohesion

  • Khái niệm: Các element được đặt với nhau vì chúng có liên quan với nhau về mặt tính năng

Đây là cohesion tốt nhất, bản thiết kế cohesion này sẽ giúp chúng ta có một đoạn mã nguồn dễ mở rộng, dễ đọc và dễ maintain.

Một ví dụ rõ ràng nhất là Stack

III. Tổng kết

Trong quá trình phát triển ứng dụng sẽ không tránh khỏi việc thay đổi nghiệp vụ hay cần chỉnh sửa mã nguồn, việc chúng ta có một bản thiết kết tốt sẽ giúp cho hệ thống thích nghi tốt hơn với sự thay đổi đó. Do đó, một bản thiết kế tốt cần có một low coupling và high cohesion, điều này sẽ giúp cho hệ thống dễ mở rộng, maintain và mã nguồn dễ hiểu dễ đọc.

Related Posts