Tính liên kết cao là gì và làm thế nào để sử dụng / tạo ra nó?


84

Tôi đang học lập trình máy tính và tại một số nơi, tôi đã vấp phải khái niệm về sự gắn kết và tôi hiểu rằng mong muốn một phần mềm có "tính liên kết cao" nhưng nó có nghĩa là gì? Tôi là một lập trình viên Java, C và Python đang học C ++ từ cuốn sách C ++ Primer đề cập đến sự gắn kết mà không có nó trong chỉ mục, bạn có thể chỉ cho tôi một số liên kết về chủ đề này không? Tôi không tìm thấy trang wikipedia về sự gắn kết trong khoa học máy tính vì nó chỉ nói rằng đó là một thước đo định tính và không đưa ra các ví dụ mã thực tế.



3
Tính liên kết cao: hành vi liên quan để ngồi cùng nhau, và hành vi không liên quan để ngồi ở nơi khác.
Teoman shipahi

Câu trả lời:


240

Tính gắn kết cao là khi bạn có một lớp thực hiện tốt công việc được xác định. Tính liên kết thấp là khi một lớp làm nhiều công việc mà không có nhiều điểm chung.

Hãy lấy ví dụ sau:

Bạn có một lớp cộng hai số, nhưng lớp đó tạo ra một cửa sổ hiển thị kết quả. Đây là một lớp có tính liên kết thấp vì cửa sổ và thao tác thêm không có nhiều điểm chung. Cửa sổ là phần trực quan của chương trình và chức năng thêm là logic đằng sau nó.

Để tạo ra một giải pháp gắn kết cao, bạn sẽ phải tạo một Cửa sổ lớp và một Tổng lớp. Cửa sổ sẽ gọi phương thức Sum để lấy kết quả và hiển thị. Bằng cách này, bạn sẽ phát triển riêng logic và GUI của ứng dụng.


14
Thành thật mà nói tôi không định nghĩa Cohesion như vậy. Định nghĩa của bạn là SRP (nguyên tắc đáp ứng đơn). Và sự gắn kết là về việc liệu các lớp có cùng quỹ đạo tính năng, thông minh của gói có gần nhau hay không.
v.oddou

4
SRP (Nguyên tắc đáp ứng đơn) chỉ là một cách khác để diễn đạt cùng một khái niệm. Sự gắn kết không chỉ là một thước đo; SRP là một hướng dẫn thực dụng mà nếu tuân theo sẽ dẫn đến các lớp gắn kết.
ComDubh

3
Tôi nghĩ rằng cửa sổ lớp không nên gọi bất kỳ đối tượng nào của lớp sum vì mục đích duy nhất của nó là hiển thị nó không cần biết về "sự tồn tại" của lớp tổng hoặc bất kỳ lớp nào khác. Nên có một lớp khác nói Driver sẽ lấy kết quả từ lớp sum và sẽ vượt qua kết quả đến lớp Window để render
Eklavyaa

1
Tôi không hiểu. Đây không phải là sự gắn kết theo mã sạch từ chú Bob. Đây là SRP
karlihnos

Giải thích rất gọn gàng! Cảm ơn
Vincent Llauderes

55

Giải thích về nó là gì từ Code Complete của Steve McConnell :

Sự liên kết đề cập đến mức độ chặt chẽ của tất cả các quy trình trong một lớp hoặc tất cả mã trong một quy trình hỗ trợ một mục đích trung tâm . Các lớp có chứa chức năng liên quan mạnh mẽ được mô tả là có sự gắn kết chặt chẽ và mục tiêu của heuristic là làm cho sự gắn kết chặt chẽ nhất có thể. Cohesion là một công cụ hữu ích để quản lý độ phức tạp vì càng nhiều mã trong một lớp hỗ trợ mục đích trung tâm, thì bộ não của bạn càng dễ nhớ mọi thứ mà mã đó làm.

Một số cách để đạt được nó từ Mã sạch của Uncle Bob :

Các lớp nên có một số lượng nhỏ các biến cá thể . Mỗi phương thức của một lớp nên thao tác với một hoặc nhiều biến đó. Nói chung , một phương thức càng thao tác nhiều biến thì phương thức đó càng gắn kết với lớp của nó. Một lớp trong đó mỗi biến được sử dụng bởi mỗi phương thức là tối đa gắn kết.

Nói chung, không nên cũng như không thể tạo các lớp gắn kết tối đa như vậy; mặt khác, chúng tôi muốn sự gắn kết cao. Khi tính liên kết cao, có nghĩa là các phương thức và biến của lớp là đồng phụ thuộc và gắn kết với nhau như một tổng thể logic.

Khái niệm về sự gắn kết có liên quan chặt chẽ với khái niệm về sự ghép nối; Ngoài ra, có một nguyên tắc dựa trên kinh nghiệm của sự gắn kết cao, được đặt tên là Nguyên tắc Trách nhiệm Đơn lẻ (chữ S từ SOLID).


1
Tôi nghĩ câu trả lời của bạn hoàn thiện hơn câu được chấp nhận, bởi vì nó mô tả cả SRP và sự gắn kết, và do đó, nó giúp hiểu được các đặc điểm cụ thể và sự khác biệt giữa hai khái niệm này.
The Once-ler

18

Tính liên kết cao là một khái niệm kỹ thuật phần mềm. Về cơ bản, nó nói rằng một lớp chỉ nên làm những gì nó được cho là phải làm và làm đầy đủ. Đừng làm quá tải nó với các chức năng mà nó không được phép làm, và bất cứ điều gì liên quan trực tiếp đến nó cũng không được xuất hiện trong mã của một số lớp khác.

Ví dụ là khá chủ quan, vì chúng tôi cũng phải xem xét quy mô. Một chương trình đơn giản không nên quá mô-đun hóa hoặc nó sẽ bị phân mảnh; trong khi một chương trình phức tạp có thể cần nhiều mức độ trừu tượng hơn để xử lý độ phức tạp.

ví dụ: Lớp email. Nó phải chứa các thành viên dữ liệu đến, from, cc, bcc, subject, body, và có thể chứa các phương thức này saveAsDraft (), send (), discardDraft (). Nhưng login () không nên ở đây, vì có một số giao thức email và nên được triển khai riêng.


Đó là định nghĩa của SRP: "một lớp chỉ nên làm những gì nó được cho là phải làm và thực hiện nó đầy đủ."
AliN11

11

Sự gắn kết thường được đo lường bằng cách sử dụng một trong các số liệu LCOM (Thiếu sự gắn kết), số liệu LCOM ban đầu đến từ Chidamber và Kemerer. Xem ví dụ: http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Một ví dụ cụ thể hơn: Nếu một lớp có ví dụ một trường riêng và ba phương thức; khi cả ba phương thức sử dụng trường này để thực hiện một hoạt động thì lớp này rất gắn kết.

Mã giả của một lớp cố kết:

class FooBar {
  private SomeObject _bla = new SomeObject();

  public void FirstMethod() {
    _bla.FirstCall();
  }

  public void SecondMethod() {
    _bla.SecondCall();
  }

  public void ThirdMethod() {
    _bla.ThirdCall();
  }
}

Nếu một lớp chẳng hạn có ba trường riêng và ba phương thức; khi cả ba phương thức chỉ sử dụng một trong ba trường thì lớp có tính liên kết kém.

Mã giả của một lớp kém gắn kết:

class FooBar {
  private SomeObject _bla = new SomeObject();
  private SomeObject _foo = new SomeObject();
  private SomeObject _bar = new SomeObject();

  public void FirstMethod() {
    _bla.Call();
  }

  public void SecondMethod() {
    _foo.Call();
  }

  public void ThirdMethod() {
    _bar.Call();
  }
}

Nguyên tắc lớp học làm một việc là Nguyên tắc Trách nhiệm Đơn lẻ đến từ Robert C. Martin và là một trong những nguyên tắc RẮN . Nguyên tắc quy định rằng một lớp chỉ nên có một lý do để thay đổi.

Việc tuân theo Nguyên tắc trách nhiệm duy nhất có thể dẫn đến mã gắn kết hơn, nhưng theo tôi đây là hai điều khác nhau.


4

Đây là một ví dụ về sự gắn kết thấp:

class Calculator
{


     public static void main(String args[])
     {

          //calculating sum here
          result = a + b;
          //calculating difference here
          result = a - b;
          //same for multiplication and division
     }
}

Nhưng tính liên kết cao ngụ ý rằng các hàm trong các lớp thực hiện những gì chúng phải làm (giống như chúng được đặt tên). Và không phải một số chức năng thực hiện công việc của một số chức năng khác. Vì vậy, những điều sau đây có thể là một ví dụ về sự gắn kết cao:

class Calculator
{


     public static void main(String args[])
     {

          Calculator myObj = new Calculator();
          System.out.println(myObj.SumOfTwoNumbers(5,7));
      }


     public int SumOfTwoNumbers(int a, int b)
     {

          return (a+b);
     }

     //similarly for other operations

}

3

Một cách chung để nghĩ về nguyên tắc gắn kết là bạn nên định vị một mã cùng với các mã khác phụ thuộc vào nó hoặc phụ thuộc vào nó. Sự liên kết có thể và nên được áp dụng cho các cấp độ thành phần trên cấp độ lớp. Ví dụ: một gói hoặc không gian tên lý tưởng nên chứa các lớp liên quan đến một số chủ đề chung và phụ thuộc lẫn nhau nhiều hơn là phụ thuộc vào các gói / không gian tên khác. Tức là giữ các phụ thuộc cục bộ.


1

kết hợp có nghĩa là một lớp hoặc một phương thức chỉ thực hiện một công việc xác định. tên của phương thức hoặc lớp cũng phải tự giải thích. Ví dụ: nếu bạn viết một máy tính, bạn nên đặt tên lớp là "máy tính" chứ không phải "asdfghj". Ngoài ra, bạn nên xem xét để tạo một phương thức cho mỗi tác vụ, ví dụ: subtract () add (), v.v. ... lập trình viên có thể sử dụng chương trình của bạn trong tương lai biết chính xác các phương thức của bạn đang làm gì. đặt tên tốt có thể làm giảm nỗ lực bình luận

cũng có một nguyên tắc là KHÔ - không lặp lại chính mình


1

Thuật ngữ liên kết ban đầu được sử dụng để mô tả các mô-đun của mã nguồn như một thước đo định tính về mức độ liên quan của mã nguồn của mô-đun với nhau. Ý tưởng về sự gắn kết được sử dụng trong nhiều lĩnh vực. Ví dụ, một nhóm người chẳng hạn như một đơn vị quân đội có thể gắn kết, có nghĩa là những người trong đơn vị làm việc cùng nhau để hướng tới một mục tiêu chung.

Bản chất của sự gắn kết mã nguồn là mã nguồn trong một mô-đun làm việc cùng nhau hướng tới một mục tiêu chung, được xác định rõ ràng. Số lượng mã nguồn tối thiểu cần thiết để tạo ra các đầu ra của mô-đun nằm trong mô-đun và không nhiều hơn. Giao diện được xác định rõ ràng và các đầu vào chảy qua giao diện và các đầu ra chảy ngược lại qua giao diện. Không có tác dụng phụ và điểm nhấn là sự tối giản.

Lợi ích của các mô-đun gắn kết về mặt chức năng là việc phát triển và tự động hóa các bài kiểm tra đơn vị rất đơn giản. Trên thực tế, một thước đo tốt về sự gắn kết của một mô-đun là việc tạo ra một bộ đầy đủ các bài kiểm tra đơn vị đầy đủ cho mô-đun dễ dàng như thế nào.

Một mô-đun có thể là một lớp trong ngôn ngữ hướng đối tượng hoặc một hàm trong ngôn ngữ chức năng hoặc ngôn ngữ không hướng đối tượng, chẳng hạn như C. Phần lớn công việc ban đầu trong lĩnh vực đo lường sự gắn kết này chủ yếu liên quan đến các chương trình COBOL tại IBM trở lại Những năm 1970 nên sự gắn kết chắc chắn không chỉ là một khái niệm hướng đối tượng.

Mục đích ban đầu của nghiên cứu mà từ đó khái niệm về sự gắn kết và khái niệm liên quan về sự kết hợp ra đời là nghiên cứu xem đặc điểm của các chương trình dễ hiểu, dễ duy trì và mở rộng ở đâu. Mục tiêu là có thể học các phương pháp lập trình tốt nhất, hệ thống hóa các phương pháp hay nhất đó và sau đó dạy các phương pháp này cho các lập trình viên khác.

Mục tiêu của các lập trình viên giỏi là viết mã nguồn có tính liên kết càng cao càng tốt với môi trường và vấn đề đang được giải quyết. Điều này ngụ ý rằng trong một ứng dụng lớn, một số phần của phần thân mã nguồn sẽ thay đổi so với các phần khác theo mức độ gắn kết của mã nguồn trong mô-đun hoặc lớp đó. Đôi khi điều tốt nhất bạn có thể nhận được là sự gắn kết theo thời gian hoặc tuần tự do vấn đề bạn đang cố gắng giải quyết.

Mức độ gắn kết tốt nhất là gắn kết chức năng. Một mô-đun có liên kết chức năng tương tự như một hàm toán học ở chỗ bạn cung cấp một tập hợp các đầu vào và bạn nhận được một đầu ra cụ thể. Một mô-đun thực sự có chức năng sẽ không có tác dụng phụ ngoài đầu ra cũng như không duy trì bất kỳ loại trạng thái nào. Thay vào đó, nó sẽ có một giao diện được xác định rõ ràng, đóng gói chức năng của mô-đun mà không để lộ bất kỳ phần nào bên trong của mô-đun và người sử dụng mô-đun sẽ cung cấp một tập hợp đầu vào cụ thể và đổi lại nhận được một đầu ra cụ thể. Một mô-đun thực sự có chức năng cũng phải an toàn.

Nhiều thư viện ngôn ngữ lập trình chứa một số ví dụ về các mô-đun chức năng cho dù là lớp, mẫu hay hàm. Các ví dụ liên kết hàm nhất sẽ là các hàm toán học như sin, cosin, căn bậc hai, v.v.

Các chức năng khác có thể có tác dụng phụ hoặc duy trì trạng thái nào đó dẫn đến việc sử dụng các chức năng đó phức tạp hơn.

Ví dụ: một hàm ném ra một ngoại lệ hoặc đặt một biến lỗi chung ( errnotrong C) hoặc phải được sử dụng trong một chuỗi ( strtok()hàm là một ví dụ từ thư viện C chuẩn vì nó duy trì trạng thái bên trong) hoặc cung cấp một con trỏ mà sau đó phải được quản lý hoặc cấp nhật ký cho một số tiện ích nhật ký là tất cả các ví dụ về một chức năng không còn gắn kết chức năng.

Tôi đã đọc cả cuốn sách gốc của Yourdon và Constantine, Lập trình có cấu trúc, nơi tôi lần đầu tiên biết đến ý tưởng về sự gắn kết vào những năm 1980 và cuốn sách Hướng dẫn thực hành về thiết kế hệ thống có cấu trúc của Meilir Page-Jones, và Page-Jones đã làm tốt hơn nhiều trong việc mô tả cả sự liên kết và sự gắn kết. Cuốn Yourdon and Constantine có vẻ hàn lâm hơn một chút. Cuốn sách Code Complete của Steve McConnell khá hay và thực tế và bản sửa đổi có khá nhiều điều để nói về thực hành lập trình tốt.


Bạn nói The minimum amount of source code needed to create the module outputs is in the module and no moređiều này không liên quan đến Cohesion mà liên quan đến DTSTTCPW
v.oddou

@ v.oddou, số lượng mã tối thiểu thực sự liên quan đến Cohesion. Càng nhiều mã trong một mô-đun không liên quan đến mô-đun đầu ra thì mã có nhiều tác dụng phụ hơn, do đó Độ gắn kết thấp hơn. Mỗi khái niệm đều có những góc nhìn khác nhau, đặc biệt là những khái niệm như Cohesion hơi mơ hồ. Các phép đo cho Cohesion là định tính yêu cầu một loại logic mờ để phân bổ một mô-đun cụ thể cho một danh mục này hoặc một danh mục khác bằng cách sử dụng một số đánh giá. Nói mã tối thiểu cho các đầu ra không phải là một đặc tính đủ cho Độ kết dính cao chỉ là một trong một số.
Richard Chambers

1

Hầu hết các câu trả lời không giải thích sự gắn kết là gì, Nó được định nghĩa rõ ràng trong mã sạch của cuốn sách chú bobs.

Các lớp nên có một số lượng nhỏ các biến cá thể. Mỗi phương thức của một lớp nên thao tác với một hoặc nhiều biến đó. Nói chung, một phương thức càng thao tác nhiều biến thì phương thức đó càng gắn kết với lớp của nó. Một lớp trong đó mỗi biến được sử dụng bởi mỗi phương thức là tối đa gắn kết. Nói chung, không nên cũng như không thể tạo các lớp gắn kết tối đa như vậy; mặt khác, chúng tôi muốn sự gắn kết cao. Khi tính liên kết cao, có nghĩa là các phương thức và biến của lớp là đồng phụ thuộc và gắn kết với nhau như một tổng thể logic.

Hãy để tôi giải thích nó với một định nghĩa lớp

class FooBar {
private _bla;
private _foo;
private _bar;

function doStuff()

   if(this._bla>10){
     this._foo = 10;
     this._bar = 20;
   }

}
function doOtherStuff(){

    if(this._foo==10){
       this._bar = 100;
       this._bla = 200;
    }
}

}

Nếu bạn thấy ví dụ trên, lớp có tính liên kết có nghĩa là các biến được chia sẻ giữa các lớp để làm việc cùng nhau nhiều biến được chia sẻ hơn có nghĩa là lớp có tính gắn kết cao và hoạt động như một đơn vị duy nhất.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.