Sự tách rời là gì và nó có thể áp dụng cho các lĩnh vực phát triển nào? [đóng cửa]


21

Gần đây tôi nhận thấy việc tách rời như một chủ đề trong một câu hỏi và muốn biết nó là gì và nó có thể áp dụng ở đâu.

Bởi "nó có thể áp dụng ở đâu", ý tôi là:

Có phải nó chỉ liên quan khi các ngôn ngữ được biên dịch như C và Java có liên quan?

Tôi có nên biết về / nghiên cứu nó như một nhà phát triển web không?


Nó sẽ giúp ích nếu bạn thực hiện một nghiên cứu nhỏ và đặt câu hỏi dựa trên bất kỳ phần không rõ ràng nào của định nghĩa.
JeffO

2
@JeffO - Tôi nghĩ rằng thế giới được hưởng lợi từ các câu hỏi khái niệm đầy đủ cũng như từ các sắc thái cụ thể. "Tại sao bầu trời màu xanh?" cho phép các câu trả lời bao gồm chính khái niệm mà không đi sâu vào chi tiết cụ thể. Đó là lý do tại sao tôi đã đi trước và hỏi câu hỏi của tôi mà không cần nghiên cứu.

Vấn đề cụ thể bạn đang gặp phải là gì? Khi đứng bây giờ, câu hỏi của bạn là nhiều quá rộng. Ở dạng hiện tại, câu trả lời về cơ bản là toàn bộ văn bản của Thiết kế có cấu trúc: Nguyên tắc cơ bản của một kỷ luật của chương trình máy tính và thiết kế hệ thống của Edward Yourdon và Larry Constantine .
Jörg W Mittag

Tôi nghĩ rằng các câu trả lời ở đây làm một công việc hoàn hảo để mô tả khái niệm. Nó giống như hỏi "Định nghĩa của từ này liên quan đến lập trình" là gì - Làm thế nào nó quá rộng? @ GlenH7

1
@ jt0dd tôi phải đồng ý. Chỉ vì bạn có thể giải thích điều gì đó bằng một cuốn sách, không có nghĩa là không có giá trị trong câu trả lời ngắn gọn hơn. Với tài liệu lập trình, mọi người thường đưa bạn vào các chi tiết trước khi đưa ra một cái nhìn tổng quan ở mức cao hơn. "OOP là gì?" sẽ là cách quá rộng. Nhưng đây là một chủ đề hợp lý cụ thể IMO.
Erik Reppen

Câu trả lời:


57

'Khớp nối' là một thuật ngữ mô tả mối quan hệ giữa hai thực thể trong một hệ thống phần mềm (thường là các lớp).

Khi một lớp sử dụng một lớp khác hoặc liên lạc với nó, nó được gọi là 'phụ thuộc' vào lớp khác đó, và vì vậy các lớp này được 'ghép'. Ít nhất một trong số họ 'biết' về người kia.

Ý tưởng là chúng ta nên cố gắng giữ cho khớp nối giữa các lớp trong hệ thống của mình ở mức 'lỏng lẻo' nhất có thể: do đó, 'khớp nối lỏng lẻo' hoặc đôi khi là 'tách rời' (mặc dù trong tiếng Anh 'tách rời' có nghĩa là 'không khớp nối', mọi người thường sử dụng nó để ám chỉ 'khớp nối lỏng lẻo' giữa các thực thể).

Vậy: khớp nối lỏng lẻo so với khớp nối mạnh trong thực tế là gì và tại sao chúng ta nên tạo ra các thực thể ghép lỏng lẻo?


Khớp nối mô tả mức độ phụ thuộc giữa thực thể này với thực thể khác. Thường các lớp hoặc đối tượng.

Khi ClassA phụ thuộc nhiều vào ClassB, khả năng ClassA bị ảnh hưởng khi ClassB bị thay đổi là rất cao. Đây là khớp nối mạnh mẽ.

Tuy nhiên, nếu ClassA phụ thuộc nhẹ vào ClassB, thì khả năng ClassA bị ảnh hưởng dưới bất kỳ hình thức nào bởi sự thay đổi mã của ClassB, là thấp. Đây là khớp nối lỏng lẻo hoặc mối quan hệ 'tách rời'.

Khớp nối lỏng lẻo là tốt vì chúng tôi không muốn các thành phần trong hệ thống của chúng tôi phụ thuộc nhiều vào nhau. Chúng tôi muốn giữ cho hệ thống của chúng tôi mô-đun, nơi chúng tôi có thể thay đổi một phần một cách an toàn mà không ảnh hưởng đến phần khác.

Khi hai phần được ghép lỏng lẻo, chúng độc lập với nhau hơn và ít bị phá vỡ hơn khi các phần khác thay đổi.

Ví dụ: khi chế tạo ô tô, bạn sẽ không muốn thay đổi bên trong động cơ để phá vỡ thứ gì đó trong vô lăng.

Trong khi điều này sẽ không bao giờ xảy ra một cách tình cờ khi chế tạo một chiếc xe hơi, những điều tương tự xảy ra với các lập trình viên mọi lúc. Khớp nối lỏng lẻo có nghĩa là để giảm nguy cơ những điều như vậy xảy ra.

Khớp nối mạnh thường xảy ra khi thực thể A biết quá nhiều về thực thể B. Nếu thực thể A đưa ra quá nhiều giả định về cách thức thực thể B hoạt động hoặc cách thức xây dựng, thì có nguy cơ cao thay đổi thực thể B sẽ ảnh hưởng đến thực thể A. Điều này là bởi vì một trong những giả định của nó về thực thể B hiện không chính xác.

Ví dụ, hãy tưởng tượng rằng là một người lái xe, bạn sẽ đưa ra một số giả định nhất định về cách động cơ của chiếc xe của bạn hoạt động.

Ngày bạn mua một chiếc xe mới với động cơ hoạt động khác (hoặc vì lý do nào đó động cơ của bạn đã được thay thế), các giả định trước đây của bạn sẽ không chính xác. Nếu bạn là mã trong máy tính, bây giờ bạn sẽ là mã không chính xác mà không hoạt động đúng.

Tuy nhiên, nếu tất cả các giả định mà với tư cách là người lái xe bạn đã thực hiện về ô tô là: A- họ có vô lăng và B- họ có bàn đạp phanh và ga, hơn là những thay đổi trong xe sẽ ảnh hưởng đến bạn, miễn là một vài giả định của bạn giữ đúng Đây là khớp nối lỏng lẻo.


Một kỹ thuật quan trọng để đạt được khớp nối lỏng lẻo là Đóng gói. Ý tưởng là một lớp ẩn các chi tiết bên trong của nó khỏi các lớp khác và cung cấp một giao diện được xác định nghiêm ngặt để các lớp khác giao tiếp với nó.

Vì vậy, ví dụ, nếu bạn đã xác định một xe đẳng cấp, đó là giao diện (phương pháp công cộng) có lẽ sẽ drive(), stop(), steerLeft(), steerRight(), getSpeed(). Đây là những phương thức mà các đối tượng khác có thể gọi trên các đối tượng Car.

Tất cả các chi tiết khác của lớp Xe hơi: cách thức hoạt động của động cơ, loại nhiên liệu mà nó sử dụng, v.v ... được ẩn khỏi các lớp khác - để ngăn chúng biết quá nhiều về Xe.

Thời điểm lớp A biết quá nhiều về lớp B: chúng ta có mối quan hệ kết nối chặt chẽ, trong đó lớp A quá phụ thuộc vào lớp B và sự thay đổi trong lớp B có thể ảnh hưởng đến lớp A. Làm cho hệ thống khó mở rộng và duy trì.

Một mối quan hệ giữa hai thực thể, nơi chúng biết rất ít về nhau (chỉ những gì cần thiết) - là mối quan hệ lỏng lẻo hoặc tách rời.


3

Decoupling nói chung là tất cả về việc xem liệu hai điều cần phải phối hợp chặt chẽ với nhau hay có thể được thực hiện độc lập hơn nữa. Độc lập là tuyệt vời vì nó làm cho những thứ đó dễ dàng thay đổi hoặc sử dụng ở một nơi khác. Việc tách rời có thể được áp dụng trong nhiều lĩnh vực, không chỉ phát triển và điều này đặc biệt đúng đối với việc tách rời theo thời gian, thậm chí có thể được áp dụng trong cuộc sống hàng ngày của bạn (ở một mức độ nào đó). Cũng cần lưu ý, có nhiều loại khớp nối trong phát triển phần mềm để xem xét, và không phải tất cả sẽ được đề cập trong câu trả lời. Bạn sẽ phải làm nghiên cứu của bạn.

Hai thứ, AB , được ghép nối nếu có sự phụ thuộc giữa chúng. Nếu A phụ thuộc vào B, bạn có thể sử dụng B mà không cần xem xét A. Nếu bạn muốn sử dụng A, bạn cũng sẽ phải mang B qua, vì A phụ thuộc vào nó.

Trong phát triển phần mềm, thông thường, bạn không thể loại bỏ hoàn toàn khớp nối giữa các thành phần. Việc tách rời trong bối cảnh đó thường có nghĩa là nới lỏng khớp nối hiện có. Đó là, đảm bảo mỗi thành phần biết ít nhất có thể về các thành phần khác xung quanh nó.

Đây có lẽ là loại khớp nối phổ biến nhất được tìm thấy trong tự nhiên:

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = (Friend[])client.GetConnection().ExecuteCommandForResult("getFriends:" + user.Name);
     ...
}

Ở đây DisplayFriends hoạt động thủ công một cách không cần thiết với kết nối phía sau ứng dụng khách Facebook để có được những gì nó cần. DisplayFriendsLớp học được kết hợp với cả hai FacebookClientConnection. Nếu FacebookClient đột nhiên thay đổi loại kết nối mà nó sử dụng, ứng dụng sẽ không thể có được bạn bè trên Facebook nữa. Chúng tôi có thể xóa khớp nối giữa lớp DisplayFriends và Connection bằng cách yêu cầu FacebookClient cung cấp những gì chúng tôi cần cho chúng tôi.

//Inside a class meant to display info for a particular Facebook user.
void DisplayFriends(FacebookUser user, FacebookClient client)
{
     Friend[] = client.GetFriends(user);
     ...
}

Bây giờ chúng tôi không thực sự quan tâm làm thế nào FacebookClient có được bạn bè của chúng tôi. Tất cả những gì chúng tôi thực sự quan tâm là thực tế là nó có được chúng. Bất kỳ thay đổi nào mang đến hành vi nội bộ của nó sẽ không làm hỏng lớp của chúng ta.

Loại tách rời này có thể dễ dàng đạt được bằng cách tuân theo Luật Demeter cho các chức năng, theo đó (trích dẫn Wikipedia):

Định luật Demeter cho các hàm yêu cầu một phương thức m của một đối tượng O chỉ có thể gọi các phương thức của các loại đối tượng sau:

  • Bản thân nó
  • thông số của m
  • Bất kỳ đối tượng được tạo / khởi tạo trong m
  • Đối tượng thành phần trực tiếp của O
  • Một biến toàn cục, có thể truy cập bằng O, trong phạm vi m

Vì tôi đã đề cập về khớp nối tạm thời trong phần đầu của câu trả lời, tôi sẽ mô tả ngắn gọn về nó.

Khớp nối tạm thời thường được xem xét khi thiết kế các ứng dụng thực thi các thuật toán song song. Xem xét hai đơn vị thực thi (có thể là hướng dẫn thực tế, phương thức hoặc bất cứ điều gì bạn muốn coi là đơn vị), A và B. Chúng tôi nói A được ghép tạm thời với B nếu B phải được thực thi trước khi A được thực thi. Nếu A không được ghép tạm thời với B, A và B có thể được thực thi cùng một lúc. Xây dựng ví dụ của riêng bạn cho điều này: nghĩ về những điều thông thường bạn làm trong cuộc sống hàng ngày. Có hai điều bạn làm lần lượt, nhưng bạn có thể làm cùng một lúc không?

Cuối cùng, để trả lời bit cuối cùng của bạn:

Tôi có nên biết về / nghiên cứu nó như một nhà phát triển web không?

Vâng. Ví dụ, một trong những mẫu thiết kế phổ biến nhất để phát triển web (MVC) là tất cả về tách rời.


1

Các câu trả lời khác làm tốt công việc mô tả sự tách rời là gì. Tôi muốn thảo luận về câu hỏi cuối cùng của bạn.

Tôi có nên biết về / nghiên cứu nó như một nhà phát triển web không?

Câu trả lời là có. Không quan trọng bạn là nhà phát triển nào. Bạn có thể là nhà phát triển web hoặc nhà phát triển hệ thống nhúng.

Giả sử bạn có một lớp tạo URL tùy chỉnh được đặt trên trang web của bạn. Bạn có thể muốn lớp viết trực tiếp các URL vào trang, đặt chúng vào href của một thẻ. Điều này có vẻ đơn giản hơn lúc đầu. Nhưng điều gì xảy ra khi bạn cần thay đổi để đưa các liên kết vào email và gửi chúng cho người dùng? Mã hiện tại của bạn sẽ không hoạt động vì trình tạo URL của bạn được kết hợp chặt chẽ với khung web bạn đang sử dụng.

Tùy chọn tốt hơn là có một lớp trình tạo URL trả về URL dưới dạng chuỗi. Điều này có thể được sử dụng bởi mã web của bạn và nó cũng có thể được sử dụng bởi mã email của bạn. Có vẻ như nhiều công việc trả trước hơn để có mã tách rời, nhưng nỗ lực tự trả tiền theo thời gian.

Có mã được mô đun hóa và tách rời sẽ giúp mã của bạn dễ hiểu hơn, dễ kiểm tra hơn và dễ bảo trì hơn, bất kể bạn đang làm việc trong lĩnh vực lập trình nào.


Sau câu trả lời này và hai câu trả lời khác, tôi thực sự hiểu điều này và xem làm thế nào tôi có thể sử dụng nó.
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.