Bạn tuân thủ nghiêm ngặt như thế nào về quy tắc Chu kỳ không phụ thuộc vào chu kỳ (NDepend)


10

Một chút thông tin cơ bản: Với tư cách là trưởng nhóm, tôi sử dụng NDepend khoảng một lần một tuần để kiểm tra chất lượng mã của chúng tôi. Đặc biệt là phạm vi kiểm tra, dòng mã và số liệu độ phức tạp chu kỳ là vô giá đối với tôi. Nhưng khi nói đến chu kỳ cân bằng và phụ thuộc, tôi hơi ... lo ngại. Patrick Smacchia có một bài đăng blog hay mô tả mục tiêu của việc san bằng.

Để rõ ràng: Trong "chu kỳ phụ thuộc" tôi hiểu một tham chiếu vòng tròn giữa hai không gian tên.

Hiện tại tôi đang làm việc trên khung GUI dựa trên Windows CE cho các công cụ nhúng - chỉ cần nghĩ về nền tảng đồ họa Android nhưng dành cho các công cụ cấp thấp. Khung này là một hội đồng duy nhất với khoảng 50.000 dòng mã (loại trừ các bài kiểm tra). Khung được chia thành các không gian tên sau:

  • Hệ thống con Điều hướng & Menu chính
  • Hệ thống con màn hình (Trình bày / Lượt xem / ...)
  • Lớp điều khiển / widget

Hôm nay tôi đã dành nửa ngày để cố gắng đưa mã đến mức phù hợp [nhờ Resharper không có vấn đề gì nói chung] nhưng trong tất cả các trường hợp, một số chu kỳ phụ thuộc tồn tại.

Vì vậy, câu hỏi của tôi: Làm thế nào để bạn tuân thủ nghiêm ngặt quy tắc "Không phụ thuộc chu kỳ"? Là mức độ thực sự quan trọng?


2
Nếu "không có chu kỳ phụ thuộc" có nghĩa là không có tham chiếu vòng tròn, thì - không có lý do. Đó là những điều ác thuần túy.
Arnis Lapsa

@ollifant: xác định chính xác ý bạn là gì khi bạn viết "Không phụ thuộc chu kỳ". Giữa các lớp hoặc giữa các lớp trong một lớp?
Doc Brown

Câu trả lời:


9

Gần đây tôi đã viết 2 cuốn sách trắng, xuất bản trên Simple-Talk về chủ đề kiến ​​trúc mã .NET (cuốn thứ nhất là về các cụm .NET, cuốn thứ hai về không gian tên và mức độ):

Phân vùng cơ sở mã của bạn thông qua các hội đồng .NET và các dự án Visual Studio

Xác định các thành phần .NET với không gian tên

Là mức độ thực sự quan trọng?

Vâng, đúng vậy!

Trích dẫn từ cuốn sách trắng thứ 2:

Nếu biểu đồ phụ thuộc giữa các thành phần có chứa một chu kỳ, các thành phần tham gia vào chu trình có thể được phát triển và kiểm tra độc lập. Bởi vì điều này, chu kỳ của các thành phần đại diện cho một siêu thành phần, với entropy cao hơn tổng các entropi của các thành phần có trong nó.

(...)

Miễn là các ràng buộc thành phần theo chu kỳ liên tục được tôn trọng, cơ sở mã vẫn có thể học được và duy trì được.

  • Trong kiến ​​trúc xây dựng truyền thống, cường độ trọng lực gây áp lực lên các cổ vật cấp thấp. Điều này làm cho chúng ổn định hơn: 'ổn định' theo nghĩa là chúng khó di chuyển.
  • Trong kiến ​​trúc phần mềm, việc tuân thủ ý tưởng thành phần theo chu kỳ sẽ gây áp lực lên các thành phần cấp thấp. Điều này làm cho chúng ổn định hơn, theo nghĩa là đau đớn khi tái cấu trúc chúng. Trừu tượng thực nghiệm thường ít phải tái cấu trúc hơn so với triển khai. vì lý do này, một ý tưởng tốt là các thành phần cấp thấp chứa phần lớn trừu tượng (giao diện và bảng liệt kê) để tránh tái cấu trúc đau đớn.

6

Tôi không bao giờ cho phép phụ thuộc vòng tròn giữa các lớp hoặc không gian tên. Trong C #, Java và C ++, bạn luôn có thể phá vỡ một phụ thuộc lớp tròn bằng cách giới thiệu một giao diện.

Mã hóa thử nghiệm đầu tiên gây khó khăn cho việc giới thiệu các phụ thuộc tròn.


4

Đó luôn là một sự đánh đổi: bạn phải hiểu chi phí của sự phụ thuộc để hiểu tại sao phải tránh sự phụ thuộc. Theo cách tương tự, nếu bạn hiểu chi phí của một phụ thuộc, bạn có thể quyết định tốt hơn nếu nó có giá trị trong trường hợp cụ thể của bạn.

Ví dụ, trong các trò chơi video trên bàn điều khiển, chúng tôi thường dựa vào các phụ thuộc khi cần mối quan hệ chặt chẽ về thông tin, chủ yếu là vì lý do hiệu suất. Điều đó tốt đến mức chúng ta không cần phải linh hoạt như một công cụ phiên bản chẳng hạn.

Nếu bạn hiểu các ràng buộc trong phần mềm, phần mềm của bạn phải chạy (là phần cứng, hệ điều hành hoặc chỉ là thiết kế (như "giao diện người dùng đơn giản hơn chúng ta có thể")) thì bạn nên dễ dàng chọn những phụ thuộc không nên làm và không nên làm đồng ý.

Nhưng nếu bạn không có lý do chính đáng và rõ ràng, hãy tránh mọi sự phụ thuộc mà bạn có thể. Mã phụ thuộc là địa ngục của phiên gỡ lỗi.


2

Bất cứ khi nào chủ đề này được thảo luận, những người tham gia thường mất trang web về sự khác biệt giữa chu kỳ thời gian xây dựng và thời gian chạy. Cái trước là cái mà John Lakos gọi là "thiết kế vật lý", trong khi cái sau về cơ bản không liên quan đến cuộc thảo luận (không bị gác máy trong các chu kỳ thời gian chạy, chẳng hạn như những cái được tạo bởi các cuộc gọi lại).

Điều này nói rằng, John Lakos đã rất nghiêm ngặt trong việc loại bỏ tất cả các chu kỳ (thời gian xây dựng). Tuy nhiên, Bob Martin đã chấp nhận thái độ chỉ chu kỳ giữa các nhị phân (ví dụ DLL, thực thi) là đáng kể và nên tránh; ông tin rằng các chu kỳ giữa các lớp trong một nhị phân không quan trọng lắm.

Cá nhân tôi giữ quan điểm của Bob Martin về điều này. Tuy nhiên, tôi vẫn chú ý đến các chu kỳ giữa các lớp vì việc không có các chu trình như vậy làm cho mã khác dễ đọc và học hơn.

Tuy nhiên, cần phải chỉ ra rằng bất kỳ mã nào bạn xây dựng với Visual Studio không có khả năng có các phụ thuộc vòng tròn giữa các nhị phân (cho dù mã gốc hoặc mã được quản lý). Do đó, vấn đề nghiêm trọng với chu kỳ đã được giải quyết cho bạn. :)


0

Gần như hoàn toàn, bởi vì các chu kỳ phụ thuộc kiểu xây dựng là bất tiện trong Haskell, và không thể có trong Agda và Coq, và đó là những ngôn ngữ tôi thường sử dụng.

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.