2008-11-23 62 views
27

tôi phải từ bỏ một lưu ý chung cho một số dự án Java khổng lồ mà tôi có nhưng tầm nhìn chút và tôi đã tự hỏi nếu có bất kỳ hướng dẫn để xác định:có bao nhiêu lớp học cho mỗi gói? phương pháp cho mỗi lớp học? dòng cho mỗi phương pháp?

  • gì số lớp mỗi gói có thể được xem xét ngay, đến thấp, hoặc cao (dự án này có 3,89 lớp học cho mỗi gói, có vẻ hơi quá nhỏ đối với tôi),
  • số phương pháp mỗi lớp? (Dự án này có 6.54 phương pháp mỗi lớp ...
  • số dòng mỗi phương pháp? (Dự án này có khoảng 7 dòng mỗi phương pháp (có vẻ khá tốt với tôi, có lẽ một chút thấp))

tôi nên Tôi có một loạt các báo cáo từ các công cụ chất lượng (checkstyle, jdepend, cpd, pmd, ncss) cho tôi tầm nhìn nhiều hơn về dự phòng mã, sử dụng lớp, lỗi, v.v.

Trả lời

23

Steve McConnell trong cuốn sách Code Complete đề xuất khoảng 7 phương pháp cho mỗi lớp và không còn dòng nào trong một phương thức có thể được xem trong một màn hình mà không cần cuộn.

Tôi không chắc chắn về các lớp học cho mỗi gói.

Tôi thực sự khuyên bạn nên đọc Hoàn tất mã để biết thêm thông tin về các chủ đề như vậy.

+27

Tôi cho rằng đề xuất này quá đơn giản. Chúng tôi không chia lớp thành hai vì chúng có nhiều hơn bảy phương pháp. Chúng ta cần suy nghĩ chủ yếu về sự gắn kết. –

+8

Bạn không phân chia chỉ vì có nhiều hơn bảy phương pháp - nhưng chỉ số này hướng sự chú ý của bạn đến lớp mà (có thể) cần tái cấu trúc. – vektor

+0

Trên màn hình trung bình (1920x1080), bạn có thể thấy khoảng 60 dòng tại thời điểm đó. Theo tôi, nó là quá nhiều cho một phương pháp duy nhất. –

15

Tôi nghĩ rằng số liệu thống kê như thế là khá vô ích, làm thế nào để biết các dòng cho mỗi phương pháp cho thấy việc sử dụng nó cho dự án hay không, tôi nghĩ bạn nên tìm kiếm nhiều hơn dọc theo các dòng:

  1. Các gói của bạn có bao gồm các lớp không?
  2. Các lớp của bạn có hoạt động như một thực thể không?
  3. Thực hiện các phương pháp trong hàm lớp chính xác và hiệu quả?

Chắc chắn ngoài việc sử dụng bộ nhớ, không quan trọng liệu phương pháp có lớn hay không? điều khác để tìm kiếm trong các phương pháp rất kéo dài là liệu dấu vết stack có lớn hơn việc thêm chức năng đó vào một phương thức cha hay không. Tôi sẽ cảnh giác với việc đo lường thành công của dự án dựa trên các dòng mã.

+0

tôi có các thống kê khác được cung cấp thông qua kiểu kiểm tra, pmd, jdepend, cpd cung cấp cho tôi thêm thông tin về những gì bạn đang nói. Câu hỏi này chỉ liên quan đến volumetry. – karlipoppins

+5

Nó hoàn toàn KHÔNG quan trọng một phương thức lớn như thế nào, vì a) một phương thức được đọc nhiều lần hơn nó được viết và b) các phương thức nhỏ dễ hiểu hơn. –

+0

Ở một điểm, vâng, nhưng nếu số dòng/phương pháp ở độ tuổi 100 hoặc 1000, tôi sẽ lo ngại rằng có thể có vấn đề với thiết kế mã, làm cho nó trở nên giòn (và có thể không được kiểm tra đầy đủ). – tvanfosson

5

Thật không may, không có khái niệm tuyệt đối (khách quan) về chất lượng trong phần mềm. Do đó, không có giá trị "đúng" cho các giá trị này. Tuy nhiên, dưới đây là hai sự phản đối cá nhân:

3.89 lớp/gói rất thấp. Nó có nghĩa là bạn sẽ chiến đấu thông qua một cây gói phức tạp.

7 Đường cho mỗi phương pháp: Thật vậy, âm thanh tốt. Tuy nhiên, nếu những con số này được đưa ra là kết quả của một nỗ lực cố ý để giảm số lượng các phương thức thì bạn có thể đã kết thúc bằng một nhiệm vụ logic duy nhất đang được lan truyền xung quanh một số phương thức riêng. trong trường hợp nhất định). Trên thực tế trong CodeComplete-2, tác giả trích dẫn một nghiên cứu đã khám phá ra rằng chiều dài phương pháp ít quan trọng hơn nhiều so với độ phức tạp của chu trình và mức độ làm tổ của nó.

13

Robert C. Martin, người vừa mới phát hành cuốn sách "Clean Code", cho biết số dòng trên mỗi phương thức nên là nhỏ nhất có thể. Từ 1-7 dòng là một nguyên tắc tốt.

Cũng có một điểm tốt trong cuốn sách ThoughtWorks Anthology, trong bài tiểu luận “Object Calisthenics” của Jeff Bay. Anh ta gợi ý 9 ràng buộc khá khó khăn để làm cho bạn trở thành một nhà phát triển OO tốt hơn trong thời gian dài. Read more about them here.

Để trả lời câu hỏi cụ thể của bạn, đó là những khó khăn đặc biệt cho bạn: - Không quá 10 lớp cho mỗi gói - Tối đa 50 dòng mỗi lớp

Những hạn chế này có thể không được lý tưởng cho tất cả các các dự án thực sự của bạn, nhưng việc sử dụng chúng trong một dự án nhỏ (sở thích?) sẽ buộc bạn phải thực hành tốt hơn.

+4

50 dòng trên mỗi lớp có vẻ khá nhỏ đối với tôi, bạn có đếm toàn bộ tệp hay chỉ các câu lệnh không? bởi vì nếu đó là toàn bộ tệp thì 50 dòng là khá nhỏ hoặc không chứa nhận xét. –

+1

Bản thân bài viết nói rằng "Những ràng buộc này được dự định là quá hạn chế, để buộc các nhà phát triển ra khỏi rãnh thủ tục." Các ý kiến ​​ở đây bao gồm rất nhiều lập luận tốt chống lại việc viết mã thế giới thực theo cách đó. –

4

Hướng dẫn thiết kế hữu ích cho biết mỗi lớp chỉ nên làm một việc và làm tốt. Điều này sẽ không cung cấp cho bạn một số phương pháp cố định cho mỗi lớp, nhưng nó sẽ giới hạn số lượng và làm cho lớp dễ hiểu hơn và duy trì.

Đối với các phương pháp, bạn có thể áp dụng chế độ xem tương tự và nhắm đến các phương pháp càng nhỏ càng tốt, nhưng không nhỏ hơn. Hãy suy nghĩ về nó theo cách này: nếu bạn có thể chia phương thức thành hai hoặc nhiều phần riêng biệt, nó rõ ràng là không nhỏ như nó có thể được. Các phương thức nhỏ dễ hiểu và bằng cách tách mã như thế này, bạn sẽ có cái nhìn tổng quan tốt hơn về các phương thức mức cao và đẩy chi tiết đến các phương thức mức thấp.

1

(lưu ý: tl; dr sẵn ở dưới cùng rất cho ý kiến ​​thật của tôi)

Tôi sẽ không trích dẫn bất kỳ tên tuổi lớn và nói đó là câu trả lời đúng, vì nó luôn luôn rất trường hợp phụ thuộc cách bạn làm tất cả những thứ này. Ví dụ: số lượng phương pháp: Nếu bạn đang tạo phần mềm điều khiển cho bộ điều khiển từ xa HD LCD TV hiện đại có khoảng 40-50 nút, bạn có thể chia nhỏ thành các lớp kết hợp để bạn chỉ có 7 phương pháp mỗi lớp?

Cá nhân tôi muốn giữ tất cả các phương pháp của một cấp độ truy cập trong một lớp, có nghĩa là một số lớp tiện ích có thể có hàng trăm phương pháp nhưng theo ý kiến ​​của tôi thì việc làm một cái gì đó như StringUtil.escapeXMLspecialCharacters(someString) dễ dàng hơn StringUtil.XML.escapeSpecialCharacters(someString) hoặc XMLUtil.escapeSpecialCharacters(someString). Trong khi tất cả những giải pháp này dường như là OK, thì giải pháp đầu tiên phát triển (ít nhất là trong tâm trí của tôi), bởi vì nó là cách đơn giản và rất dễ dàng để truy cập phương thức đó: Bạn không cần phải nghĩ rằng chuỗi bạn đang xử lý có chứa XML hoặc XHTML hoặc JSON hoặc bất cứ thứ gì, bạn sẽ chỉ chọn một phương thức từ nhóm phương pháp chung và đó là nó.

Giữ trên tương tự từ xa TV trước đó, cho phép giả sử bạn chia chúng thành các lớp khác nhau. Nếu chúng ta cho phép mình có 7 phương pháp trên mỗi lớp trung bình và quản lý nhóm các nút trên điều khiển từ xa thành các nhóm nhạy cảm như MenuButtons, AdjustmentButtons và 'NumberSelectorButtons', chúng tôi kết thúc với 8 lớp học. Đó không phải là một điều xấu thực sự, nhưng nó được hơi khó hiểu một cách dễ dàng đặc biệt là nếu họ không chia cho các nhóm nhạy cảm với sự chăm sóc tuyệt vời. Chỉ cần tưởng tượng các rants xung quanh văn phòng TVRemotes'R'Us Inc của bạn: "Ai nói nút bật/tắt nguồn là nút điều khiển?" "Ai là joker đặt âm lượng +/- vào nút menu? PRE/CH (nút chuyển giữa kênh hiện tại và kênh trước đó và/hoặc nguồn hình ảnh) Nút không phải là nút số!" "Nút hướng dẫn mở cả hướng dẫn TV và menu điều hướng tùy theo ngữ cảnh, chúng ta sẽ làm gì với nó !?" Vì vậy, như bạn có thể hy vọng nhìn thấy từ ví dụ này, sử dụng một số tùy ý để giới hạn bản thân có thể giới thiệu một số phức tạp không cần thiết và phá vỡ dòng chảy logic của ứng dụng. Ví dụ:

Trước khi tôi ném vào hai xu cuối cùng của tôi, một điều về số dòng trên mỗi phương pháp: Hãy suy nghĩ mã dưới dạng khối.Mỗi vòng lặp là một khối, mỗi khối có điều kiện là một khối và vân vân, v.v. Số tiền tối thiểu của các khối này cần thiết cho một đơn vị mã có trách nhiệm duy nhất là gì? Đó sẽ là giới hạn của bạn, không phải là mong muốn có "Bảy ở khắp mọi nơi." từ số lượng các lớp trong gói, các phương thức trong các lớp và các dòng mã trong các phương thức.

Và đây là TL; DR:

Vì vậy, ý kiến ​​thật của tôi là thực sự này: Số lượng các lớp trong gói nên được khá thấp. Gần đây tôi đã bắt đầu thực hiện những việc sau nhưng tôi không chắc chắn liệu mình có tiếp tục theo dõi hay không:

  • Gói foo chứa giao diện và các lớp phổ biến khác để triển khai.
  • Gói foo.bar chứa thực hiện các giao diện nói cho chức năng bar
  • Gói foo.baz chứa thực hiện các giao diện nói cho chức năng baz

này thường có nghĩa toàn bộ cấu trúc của tôi có một mạch lạc (và có khả năng thấp nhất) số lớp và bằng cách đọc các giao diện cấp cao nhất (và ý kiến ​​của họ), tôi cũng có thể hiểu các gói khác.

Phương pháp mỗi lớp: Tất cả những gì cần thiết như tôi đã giải thích ở trên. Nếu lớp học của bạn không thể sống mà không có 170 phương pháp, sau đó để cho nó có chúng. Tái cấu trúc là một đức hạnh, không phải là thứ có thể được áp dụng mọi lúc.

Đường cho mỗi phương pháp: Thấp nhất có thể, tôi thường kết thúc với 10 đến 25 dòng cho mỗi phương pháp và 25 là hơi cao đối với tôi vì vậy tôi muốn nói 10 là điểm cân bằng tốt cho điều đó.

Các vấn đề liên quan