2009-10-10 14 views
7

1. Về PMD:phân tích Mã số: PMD & FindBugs

1.1 Làm thế nào để thiết lập các kiểm tra PMD, bỏ qua một số trong số họ, như "Tên biến là quá ngắn, hoặc quá dài", "Hủy bỏ constructor rỗng, vv "- và nếu tôi làm điều đó, một cảnh báo khác xuất hiện cho biết lớp đó phải có một số phương thức tĩnh. Về cơ bản, lớp học trống rỗng, để phát triển sau này, và tôi muốn rời khỏi nó theo cách đó.

1.2 Bạn có cần phải làm theo lời khuyên cảnh báo này không?

A class which only has private constructors should be final 

1.3 Điều đó nghĩa là gì?

The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17) 

1.4 Cái này thì sao? Tôi rất thích sự thay đổi này, nhưng không đi qua tâm trí của tôi tại thời điểm này liên quan đến sự thay đổi:

Assigning an Object to null is a code smell. Consider refactoring. 

FindBugs 2.Regarding:

2.1 Có thực sự xấu để viết thư cho một lĩnh vực tĩnh, tại một số điểm sau tuyên bố của nó? Mã sau đây cho tôi cảnh báo:

Main.appCalendar = Calendar.getInstance(); 
Main.appCalendar.setTimeInMillis(System.currentTimeMillis()); 

nơi appCalendar là biến tĩnh.

2.2 Mã này:

strLine = objBRdr.readLine().trim(); 

đưa ra cảnh báo:

Immediate dereference of the result of readLine() 

nơi objBRdr là một BufferedReader(FileReader). Điều gì có thể xảy ra? readLine() có thể là null? Mã được lồng trong thử nghiệm while (objBRdr.ready()) và cho đến nay, tôi không có vấn đề gì ở đó.

Update1: 2.2 đã được cố định khi tôi thay thế mã với:

strLine = objBRdr.readLine(); 
    if (strLine != null) { 
     strLine = strLine.trim(); 
    } 
+0

Vâng .. tôi có thể nói gì? Tôi tò mò về con người :-). Cảm ơn các liên kết. – hypercube

+0

Cảm ơn u @Svante về chỉnh sửa. – hypercube

Trả lời

9

1,1 Làm thế nào để tôi thiết lập các kiểm tra PMD [...]

cửa hàng PMD cai trị cấu hình trong một kho lưu trữ đặc biệt được gọi là các tập tin XML ruleset.Tệp cấu hình này chứa thông tin về các quy tắc hiện được cài đặt và các thuộc tính của chúng.

Các tệp này nằm trong thư mục rulesets của bản phân phối PMD. Khi sử dụng PMD với Eclipse, hãy kiểm tra Customizing PMD.

1.2 Bạn có cần làm theo lời khuyên cảnh báo này không?

A class which only has private constructors should be final 

Tất cả các nhà thầu luôn bắt đầu bằng cách gọi hàm tạo siêu lớp. Nếu hàm khởi tạo có chứa một lời gọi đến một hàm tạo siêu lớp, thì hàm tạo đó được sử dụng. Nếu không thì hàm tạo không có đối số được ngụ ý. Nếu hàm tạo không có đối số không tồn tại hoặc không hiển thị với lớp con, bạn sẽ gặp lỗi thời gian biên dịch.

Vì vậy, thực sự không thể lấy được một lớp con từ một lớp mà mọi hàm tạo là riêng tư. Việc đánh dấu một lớp như vậy là final do đó là một ý tưởng hay (nhưng không cần thiết) vì nó ngăn chặn việc phân lớp một cách rõ ràng.

1.3 Điều đó nghĩa là gì?

The class 'Dog' has a Cyclomatic Complexity of 3 (Highest = 17) 

Sự phức tạp là số điểm quyết định trong một phương pháp cộng với một cho mục phương pháp. Các điểm quyết định là 'if', 'while', 'for' và 'nhãn trường hợp'. Nói chung, 1-4 là độ phức tạp thấp, 5-7 cho thấy độ phức tạp vừa phải, 8-10 là độ phức tạp cao và 11+ là độ phức tạp rất cao.

Sau những gì đã nói, tôi sẽ chỉ trích dẫn một số bộ phận của Aggregate Cyclomatic complexity is meaningless:

[...] Số liệu này chỉ có ý nghĩa trong bối cảnh của một phương pháp duy nhất. Đề cập đến một lớp có độ phức tạp Cyclomatic của X là vô dụng.

Vì các biện pháp phức tạp về biên độ đường dẫn theo phương pháp, mọi phương pháp đều có ít nhất là độ phức tạp của 1, ? Vì vậy, phương pháp getter sau có một giá trị CCN trong tổng số 1:

public Account getAccount(){ 
    return this.account; 
} 

Rõ ràng từ phương pháp boogie này rằng account là một tài sản của lớp này. Bây giờ hãy tưởng tượng rằng lớp này có 15 thuộc tính và theo mô hình getter/setter điển hình cho mỗi thuộc tính và đó là các phương thức duy nhất có sẵn. Điều đó có nghĩa là lớp học có 30 phương pháp đơn giản, mỗi phương pháp có giá trị phức tạp Cyclomatic là 1. Giá trị tổng hợp của lớp là 30.

Giá trị này có ý nghĩa gì không? Tất nhiên, xem nó theo thời gian có thể mang lại điều thú vị; tuy nhiên, riêng của nó, như một giá trị tổng hợp, nó về cơ bản là vô nghĩa. 30 cho lớp có nghĩa là không có gì, 30 cho một phương thức có nghĩa là một cái gì đó mặc dù.

Lần sau khi bạn thấy mình đọc một tổng Cyclomatic giá trị phức tạp copasetic cho một lớp , chắc chắn rằng bạn hiểu làm thế nào nhiều phương pháp lớp chứa. Nếu tổng độ phức tạp của Cyclomatic giá trị của một lớp là 200– không nên tăng bất kỳ cờ đỏ nào cho đến khi bạn biết số phương thức . Còn gì nữa, nếu bạn thấy rằng số lượng phương thức thấp hơn giá trị phức tạp của Cyclomatic là cao, bạn hầu như luôn tìm thấy sự phức tạp được bản địa hóa theo phương pháp. Ngay trên!

Vì vậy, với tôi, quy tắc PMD này nên được thực hiện cẩn thận (và thực sự không phải là rất có giá trị).

1.4 Cái này thì sao? Tôi rất thích sự thay đổi này, nhưng không đi qua tâm trí của tôi tại thời điểm này liên quan đến sự thay đổi:

Assigning an Object to null is a code smell. Consider refactoring. 

Không chắc những gì bạn không nhận được khoảng này.

2.1 Có thực sự là xấu khi viết vào một trường tĩnh, tại một số điểm sau tuyên bố của nó? [...]

Tôi đoán là bạn sẽ nhận được cảnh báo vì phương pháp chứa khởi tạo lười không đồng bộ của trường tĩnh không biến động. Và bởi vì trình biên dịch hoặc bộ xử lý có thể sắp xếp lại các lệnh, các luồng không được đảm bảo để xem một đối tượng được khởi tạo hoàn toàn, nếu phương thức có thể được gọi bởi nhiều luồng. Bạn có thể làm cho trường biến động để sửa vấn đề.

2,2 [...] Immediate dereference of the result of readLine()

Nếu không có nhiều dòng văn bản để đọc, readLine() sẽ trả về null và dereferencing mà sẽ tạo ra một con trỏ ngoại lệ null. Vì vậy, bạn cần thực sự để kiểm tra xem kết quả là null.

+0

Cảm ơn người đàn ông, phản hồi tuyệt vời, như mọi khi. Mặc dù "cyclomatic" âm thanh ma quái, không phải là tất cả những gì xấu bây giờ :-). Tôi mong được đọc các chỉnh sửa tiếp theo của bạn về phản hồi này và có vẻ như ứng cử viên chính cho phản hồi tốt nhất, cho đến nay. Tôi đã thực sự phát hiện ra rằng cả hai trình cắm thêm PMD và FindBugs đều có kiểm tra cảnh báo UI có thể lựa chọn..như tôi không thể yêu cầu điều đó. – hypercube

+0

Well..compile chính mình và chỉnh sửa các phản ứng xin vui lòng, vì vậy tôi có thể chọn nó như là câu trả lời tốt nhất :-). Cảm ơn. – hypercube

+0

Kịch bản sẽ đi tắm và sau đó sẽ làm việc trên đó. –

2

Dưới đây một số ý tưởng/câu trả lời

1,4 lý do để gán null tới một đối tượng là gì? Nếu bạn sử dụng lại cùng một biến, không có lý do để đặt nó thành null trước đó.

2.1 Lý do về cảnh báo này, là đảm bảo rằng tất cả phiên bản của lớp của bạn đều có cùng các trường tĩnh. Trong lớp Chính của bạn, bạn có thể có ứng dụng Lịch tĩnhCalendar = Calendar.getInstance();

về 2.2 bạn đúng, với kiểm tra rỗng, bạn chắc chắn rằng bạn sẽ không có bất kỳ NullPointerException nào. Chúng tôi không bao giờ biết khi nào BufferedReader của bạn có thể chặn/thùng rác, điều này không xảy ra thường xuyên (theo kinh nghiệm của tôi) nhưng chúng tôi không bao giờ biết khi nào một sự cố ổ cứng.

+0

+1 cho phản hồi theo chủ đề của bạn. Cảm ơn. – hypercube

+0

Tôi đang sử dụng một cái gì đó như Dog dụ = null, để buộc một số thành phần trực quan vẽ lại, trên một số sự kiện nhất định. – hypercube

+0

Định nghĩa của bạn về độ phức tạp của chu trình là ** sai **. Độ phức tạp Cyclomatic của một phương thức là số lượng đường dẫn độc lập của một phương thức. Xem http://en.wikipedia.org/wiki/Cyclomatic_complexity. –