Code Quality
                               What is this s**t?




                          Steve Hayes - Cogent Consulti...
In 1990 there were 120 billion lines of code




Friday, 28 August 2009                                                  2
In 2000 there were 250 billion lines of code




Friday, 28 August 2009                                                  3
In 2010 there will be 500 billion lines of code




Friday, 28 August 2009                                                ...
Printed in a font 1mm high
               the code listing would stretch
               from the Earth to the Moon
       ...
Code Quality



Friday, 28 August 2009                  6
Code quality is subjective - it requires human
                                       judgment




Friday, 28 August 2009 ...
There have been, and always will be, arguments
                               about code quality




Friday, 28 August 200...
Friday, 28 August 2009   9
WTF implies lack of clarity




Friday, 28 August 2009                                 10
“Simplicity, clarity, singleness: These are the
               attributes that give our lives power and vividness
        ...
Clear code is easier to understand, easier to
                                maintain, and easier to extend




Friday, 2...
There are many things that can reduce the clarity
                             of code, including:

                      ...
Your particular bugbears may be different




Friday, 28 August 2009                                               14
Why metrics?




Friday, 28 August 2009                  15
We substitute metrics for human judgement




Friday, 28 August 2009                                               16
Friday, 28 August 2009   17
People are expensive, CPU time is cheap




Friday, 28 August 2009                                             18
Use automation to detect clarity problems, such
             as:

                         •   inconsistent style
        ...
Use exception based reporting so that people can
                            focus their energy




Friday, 28 August 2009...
on the quality exceptions




Friday, 28 August 2009                               21
or on completely different things




Friday, 28 August 2009                                       22
Friday, 28 August 2009   23
Code Analysis



Friday, 28 August 2009                   24
Let’s start with some Ruby

                         Formtastic by Justin French




Friday, 28 August 2009               ...
Then we’ll move on to some Java




Friday, 28 August 2009                                     26
Duplication



Friday, 28 August 2009                 27
Friday, 28 August 2009   28
Duplication makes everything else worse




Friday, 28 August 2009                                         29
Friday, 28 August 2009   30
Initial analysis of Formtastic




Friday, 28 August 2009                                    31
37 Roodi problems

                         95 Flog problems




Friday, 28 August 2009                       32
Simian
                         http://www.redhillconsulting.com.au/products/simian/




Friday, 28 August 2009           ...
Simian - Similarity Analyser | Duplicate Code Detection for the Enterprise                          14/08/09 3:41 AM




 ...
Simian highlights obvious duplication




Friday, 28 August 2009                                           35
Similarity Analyser 2.2.24 - http://www.redhillconsulting.com.au/products/simian/index.html
                     Copyright...
Flay
                         http://ruby.sadi.st/Flay.html




Friday, 28 August 2009                                   37
Confessions of a Ruby Sadist sudo gem install flay                                               14/08/09 3:46 AM




    ...
Flay detects more subtle duplication




Friday, 28 August 2009                                          39
Total score (lower is better) = 2637              8) Similar code found in :iter (mass = 96)
                             ...
So what did I do?




Friday, 28 August 2009                       41
move lines around

                         change similar code to be the same

                         changed in-line c...
these are often non-trivial changes




Friday, 28 August 2009                                         43
very little change in overall file length

                                 (3013 => 2897 lines)




Friday, 28 August 2009...
How did that change complexity?




Friday, 28 August 2009                                     45
37 => 37 Roodi problems

                         95 => 38 Flog problems




Friday, 28 August 2009                       ...
Flog change indicates that methods have
                                     become simpler




Friday, 28 August 2009    ...
Exacerbation




Friday, 28 August 2009                  48
Friday, 28 August 2009   49
What else exacerbates problems?




Friday, 28 August 2009                                     50
Long classes and methods




Friday, 28 August 2009                              51
http://farm4.static.flickr.com/3060/2426522019_7e696fb9af.jpg




Friday, 28 August 2009                                   ...
Tools that detect long classes and methods are
                                        simple but useful




Friday, 28 Au...
Roodi
                              Ruby Object Oriented Design Inferometer
                         http://github.com/mar...
General Purpose Code Quality




Friday, 28 August 2009                                  55
Roodi checks

       AssignmentInConditionalCheck      Check for an assignment inside a conditional. It‘s probably a mista...
Roodi parameters

           AssignmentInConditionalCheck

           CaseMissingElseCheck

           ClassLineCountCheck...
lib/formtastic.rb:8      -   Module "Formtastic" has 1272 lines. It should have 300 or less.
          lib/formtastic.rb:1...
spec/formtastic_spec.rb:38 - Block cyclomatic complexity is 5. It should be 4 or less.
                         spec/formt...
Let’s work through the spec first




Friday, 28 August 2009                                      60
spec/formtastic_spec.rb:38 - Block cyclomatic
                    complexity is 5. It should be 4 or less.




Friday, 28 ...
spec/formtastic_spec.rb:109 - Case statement
                    is missing an else clause.




Friday, 28 August 2009    ...
Existing code



                         Post.stub!(:reflect_on_association).and_return do |column_name|
                ...
New code

         def mock_post_association(column_name)
           return mock_association(Author, :belongs_to) if colum...
spec/formtastic_spec.rb:1744   -   Block   cyclomatic   complexity   is   5.    It should be 4 or less.
                  ...
Not worth addressing these




Friday, 28 August 2009                                66
Back to the non-test code




Friday, 28 August 2009                               67
lib/formtastic.rb:8      -   Module "Formtastic" has 1272 lines. It should have 300 or less.
          lib/formtastic.rb:1...
(and now I make lots of code changes)




Friday, 28 August 2009                                           69
lib/formtastic.rb:115 - Don't use class variables. You might want to try a different design.
          lib/formtastic.rb:3...
and I decide that’s enough for now




Friday, 28 August 2009                                        71
How does this change flog?




Friday, 28 August 2009                               72
Old and new flog warnings

          >88.1: SemanticFormBuilder#date_or_datetime_input         60.4: SemanticFormBuilder#in...
Changes

          >88.1: SemanticFormBuilder#date_or_datetime_input        45.3: SemanticFormBuilder#database_column_inpu...
So what’s Flog?




Friday, 28 August 2009                     75
Confessions of a Ruby Sadist sudo gem install flog                                                14/08/09 3:34 AM




   ...
Confessions of a Ruby Sadist sudo gem install flog                                                 14/08/09 3:34 AM




  ...
Flog weights
       THRESHOLD = 0.60
       SCORES = Hash.new 1                                 # various "magic" usually ...
flog -d lib/formtastic.rb




Friday, 28 August 2009                              79
Flog details for worst method
                          60.4: SemanticFormBuilder#inputs
                              16....
Original code

           def inputs(*args, &block)
             html_options = args.extract_options!
             html_op...
First change
           def inputs(*args, &block)
             html_options = args.extract_options!
             html_opti...
Flog details
                         29.8: SemanticFormBuilder#build_default_inputs_args
                              9....
Next change
           def inputs(*args, &block)
             html_options = args.extract_options!
             html_optio...
Flog details - only one significant method


                            29.8: SemanticFormBuilder#build_default_inputs_arg...
Inline to_proc




           def build_default_inputs_args()
             args = @object.class.reflections.map { |n,_| n ...
Flog details


                         22.4: SemanticFormBuilder#build_default_inputs_args
                             1...
Extract method


           def build_default_inputs_args()
             args = @object.class.reflections.map { |n,_| n if...
Flog details


                         16.6: SemanticFormBuilder#build_default_inputs_args
                              ...
and so forth...




Friday, 28 August 2009                     90
Other Ruby code quality tools




Friday, 28 August 2009                                   91
Code churn metric




Friday, 28 August 2009                       92
Saikuro : A Cyclomatic Complexity Analyzer                                                        14/08/09 5:05 AM




   ...
reek, a code smells detector for ruby « silk and spinach                                              14/08/09 5:06 AM



...
RCov - Ruby C0 Code Coverage                                       15/08/09 12:11 PM




                          RCov
  ...
metric fu




Friday, 28 August 2009               96
rake metrics:all




Friday, 28 August 2009                      97
results at
                         file:///Users/stevehayes/projects/third-party/
                         formtastic/tmp/...
Java time




Friday, 28 August 2009               99
Example code is from Apache
                          Commons Collections 3.2.1




Friday, 28 August 2009                ...
Simian for duplication detection




Friday, 28 August 2009                                      101
java -jar simian-2.2.24.jar src/**/*.java




Friday, 28 August 2009                                           102
Found 11527 duplicate lines in 871 blocks in 239 files

                     Processed a total of 41324 significant (109875 ...
27.9% of the code is duplicated




Friday, 28 August 2009                                     104
Simian can also be language
                                  sensitive




Friday, 28 August 2009                        ...
java -jar simian-2.2.24.jar
                             -language=java src/**/*.java




Friday, 28 August 2009          ...
PMD for duplication detection




Friday, 28 August 2009                                   107
Android Rules: These rules deal with the Android SDK, mostly related to best practices. To get better results, make sure
 ...
Basic Rules: The Basic Ruleset contains a collection of good practices which everyone should follow.
               •    B...
Basic Rules
             •       Empty catch block                   •   Unnecessary final modifier
             •       Emp...
Basic Rules - 725
    /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java...
Braces Rules


                         •   If statements must use braces
                         •   While loops must us...
Braces Rules - 210
    /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.jav...
Clone Rules

             • Proper clone implementation (should include super.clone())
             • Clone throws CloneNo...
Clone Rules - 25
    /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList...
Code Size Rules

                         •   NPath complexity (200)
                         •   Excessive method length ...
Code Size Rules - 338
    /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap....
Coupling Rules


             • Coupling between objects (attributes, local variables,
                     return types) ...
Coupling Rules - 63
    /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.ja...
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Code Quality in Ruby and Java
Upcoming SlideShare
Loading in...5
×

Code Quality in Ruby and Java

3,132

Published on

This presentation was originally given at the Agile 2009 conference in Chicago

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,132
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
140
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Code Quality in Ruby and Java

  1. 1. Code Quality What is this s**t? Steve Hayes - Cogent Consulting Pty Ltd http://www.cogentconsulting.com.au steve.hayes@cogentconsulting.com.au Friday, 28 August 2009 1
  2. 2. In 1990 there were 120 billion lines of code Friday, 28 August 2009 2
  3. 3. In 2000 there were 250 billion lines of code Friday, 28 August 2009 3
  4. 4. In 2010 there will be 500 billion lines of code Friday, 28 August 2009 4
  5. 5. Printed in a font 1mm high the code listing would stretch from the Earth to the Moon and beyond Friday, 28 August 2009 5
  6. 6. Code Quality Friday, 28 August 2009 6
  7. 7. Code quality is subjective - it requires human judgment Friday, 28 August 2009 7
  8. 8. There have been, and always will be, arguments about code quality Friday, 28 August 2009 8
  9. 9. Friday, 28 August 2009 9
  10. 10. WTF implies lack of clarity Friday, 28 August 2009 10
  11. 11. “Simplicity, clarity, singleness: These are the attributes that give our lives power and vividness and joy as they are also the marks of great art. The seem to be the purpose of God for his whole creation.” Richard Holloway Friday, 28 August 2009 11
  12. 12. Clear code is easier to understand, easier to maintain, and easier to extend Friday, 28 August 2009 12
  13. 13. There are many things that can reduce the clarity of code, including: • inconsistent style • long methods • lots of methods in a single class • repeated code • methods with many alternative paths Friday, 28 August 2009 13
  14. 14. Your particular bugbears may be different Friday, 28 August 2009 14
  15. 15. Why metrics? Friday, 28 August 2009 15
  16. 16. We substitute metrics for human judgement Friday, 28 August 2009 16
  17. 17. Friday, 28 August 2009 17
  18. 18. People are expensive, CPU time is cheap Friday, 28 August 2009 18
  19. 19. Use automation to detect clarity problems, such as: • inconsistent style • long methods • lots of methods in a single class • repeated code • methods with many alternative paths Friday, 28 August 2009 19
  20. 20. Use exception based reporting so that people can focus their energy Friday, 28 August 2009 20
  21. 21. on the quality exceptions Friday, 28 August 2009 21
  22. 22. or on completely different things Friday, 28 August 2009 22
  23. 23. Friday, 28 August 2009 23
  24. 24. Code Analysis Friday, 28 August 2009 24
  25. 25. Let’s start with some Ruby Formtastic by Justin French Friday, 28 August 2009 25
  26. 26. Then we’ll move on to some Java Friday, 28 August 2009 26
  27. 27. Duplication Friday, 28 August 2009 27
  28. 28. Friday, 28 August 2009 28
  29. 29. Duplication makes everything else worse Friday, 28 August 2009 29
  30. 30. Friday, 28 August 2009 30
  31. 31. Initial analysis of Formtastic Friday, 28 August 2009 31
  32. 32. 37 Roodi problems 95 Flog problems Friday, 28 August 2009 32
  33. 33. Simian http://www.redhillconsulting.com.au/products/simian/ Friday, 28 August 2009 33
  34. 34. Simian - Similarity Analyser | Duplicate Code Detection for the Enterprise 14/08/09 3:41 AM Simian - Similarity Analyser Purpose Simian (Similarity Analyser) identifies duplication in Java, C#, C, C++, COBOL, Ruby, JSP, ASP, HTML, XML, Visual Basic, Groovy source code and even plain text files. In fact, simian can be used on any human readable files such as ini files, deployment descriptors, you name it. Especially on large enterprise projects, it can be difficult for any one developer to keep track of all the features (classes, methods, etc.) of the system. Simian runs natively in any .NET 1.1 or higher supported environment and on any Java 1.4 or higher virtual machine, meaning Simian can be run on just about any hardware and any operating system you can hope for. Both the Java and .NET runtimes are included as part of the distribution. Simian can be used as part of the build process during development or as a guide when re-factoring. Think of Simian as an independent pair of eyes that will assist in raising the quality of your software. Within minutes, Simian can save you literally thousands of dollars in time spent performing maintenence, debugging and re-factoring. With licensing available to suite personal, project and enterprise use, simian is ideally suited for use on your project. Why do I need Simian? Imagine for example that a bug is discovered in a method somewhere in a project. The developer duly writes a test case, makes the necessary code changes, ensures the test passes, checks the code in and considers the job finished! Right? Friday, 28 August 2009 34
  35. 35. Simian highlights obvious duplication Friday, 28 August 2009 35
  36. 36. Similarity Analyser 2.2.24 - http://www.redhillconsulting.com.au/products/simian/index.html Copyright (c) 2003-08 RedHill Consulting Pty. Ltd. All rights reserved. Simian is not free unless used solely for non-commercial or evaluation purposes. {failOnDuplication=true, ignoreCharacterCase=true, ignoreCurlyBraces=true, ignoreIdentifierCase=true, ignoreModifiers=true, ignoreStringCase=true, threshold=6} Found 7 duplicate lines in the following files: Between lines 949 and 962 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 969 and 982 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Found 7 duplicate lines in the following files: Between lines 2552 and 2562 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 2752 and 2762 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Found 11 duplicate lines in the following files: Between lines 1429 and 1446 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Between lines 1758 and 1775 in /Users/stevehayes/projects/third-party/formtastic/spec/formtastic_spec.rb Found 50 duplicate lines in 6 blocks in 1 files Processed a total of 2066 significant (4341 raw) lines in 6 files Processing time: 0.144sec Friday, 28 August 2009 36
  37. 37. Flay http://ruby.sadi.st/Flay.html Friday, 28 August 2009 37
  38. 38. Confessions of a Ruby Sadist sudo gem install flay 14/08/09 3:46 AM Ruby Sadist Flog Flay Heckle Kittens About Us Confessions of a Ruby Sadist sudo gem install flay Flay analyzes ruby code for structural similarities. Differences in literal values, names, whitespace, and programming style are all ignored. Code that flay reports as similar is a good candidate for refactoring. Try this: % sudo gem install flay % flay lib/*.rb and see what you find. Friday, 28 August 2009 38
  39. 39. Flay detects more subtle duplication Friday, 28 August 2009 39
  40. 40. Total score (lower is better) = 2637 8) Similar code found in :iter (mass = 96) spec/formtastic_spec.rb:1825 spec/formtastic_spec.rb:1831 1) Similar code found in :iter (mass = 342) spec/formtastic_spec.rb:1844 spec/formtastic_spec.rb:1570 spec/formtastic_spec.rb:1877 spec/formtastic_spec.rb:1616 spec/formtastic_spec.rb:1895 spec/formtastic_spec.rb:1914 2) Similar code found in :iter (mass = 136) spec/formtastic_spec.rb:1183 9) Similar code found in :iter (mass = 92) spec/formtastic_spec.rb:2147 spec/formtastic_spec.rb:2235 spec/formtastic_spec.rb:2313 spec/formtastic_spec.rb:2245 spec/formtastic_spec.rb:2368 10) Similar code found in :block (mass = 84) 3) IDENTICAL code found in :iter (mass*2 = 136) spec/formtastic_spec.rb:1900 spec/formtastic_spec.rb:1458 spec/formtastic_spec.rb:1919 spec/formtastic_spec.rb:1787 11) IDENTICAL code found in :block (mass*2 = 84) 4) IDENTICAL code found in :iter (mass*2 = 120) spec/formtastic_spec.rb:187 spec/formtastic_spec.rb:1069 spec/formtastic_spec.rb:194 spec/formtastic_spec.rb:1133 12) Similar code found in :iter (mass = 84) 5) IDENTICAL code found in :iter (mass*2 = 104) spec/formtastic_spec.rb:774 spec/formtastic_spec.rb:232 spec/formtastic_spec.rb:830 spec/formtastic_spec.rb:392 13) Similar code found in :iter (mass = 78) 6) Similar code found in :iter (mass = 100) spec/formtastic_spec.rb:1208 spec/formtastic_spec.rb:2572 spec/formtastic_spec.rb:1239 spec/formtastic_spec.rb:2771 spec/formtastic_spec.rb:1265 7) Similar code found in :iter (mass = 98) 14) Similar code found in :iter (mass = 75) spec/formtastic_spec.rb:408 spec/formtastic_spec.rb:596 spec/formtastic_spec.rb:419 spec/formtastic_spec.rb:602 spec/formtastic_spec.rb:608 Friday, 28 August 2009 40
  41. 41. So what did I do? Friday, 28 August 2009 41
  42. 42. move lines around change similar code to be the same changed in-line constants to variables Friday, 28 August 2009 42
  43. 43. these are often non-trivial changes Friday, 28 August 2009 43
  44. 44. very little change in overall file length (3013 => 2897 lines) Friday, 28 August 2009 44
  45. 45. How did that change complexity? Friday, 28 August 2009 45
  46. 46. 37 => 37 Roodi problems 95 => 38 Flog problems Friday, 28 August 2009 46
  47. 47. Flog change indicates that methods have become simpler Friday, 28 August 2009 47
  48. 48. Exacerbation Friday, 28 August 2009 48
  49. 49. Friday, 28 August 2009 49
  50. 50. What else exacerbates problems? Friday, 28 August 2009 50
  51. 51. Long classes and methods Friday, 28 August 2009 51
  52. 52. http://farm4.static.flickr.com/3060/2426522019_7e696fb9af.jpg Friday, 28 August 2009 52
  53. 53. Tools that detect long classes and methods are simple but useful Friday, 28 August 2009 53
  54. 54. Roodi Ruby Object Oriented Design Inferometer http://github.com/martinjandrews/roodi/tree/master Friday, 28 August 2009 54
  55. 55. General Purpose Code Quality Friday, 28 August 2009 55
  56. 56. Roodi checks AssignmentInConditionalCheck Check for an assignment inside a conditional. It‘s probably a mistaken equality comparison. CaseMissingElseCheck Check that case statements have an else statement so that all cases are covered. ClassLineCountCheck Check that the number of lines in a class is below the threshold. ClassNameCheck Check that class names match convention. CyclomaticComplexityBlockCheck Check that the cyclomatic complexity of all blocks is below the threshold. CyclomaticComplexityMethodCheck Check that the cyclomatic complexity of all methods is below the threshold. EmptyRescueBodyCheck Check that there are no empty rescue blocks. ForLoopCheck Check that for loops aren‘t used (Use Enumerable.each instead) MethodLineCountCheck Check that the number of lines in a method is below the threshold. MethodNameCheck Check that method names match convention. ModuleLineCountCheck Check that the number of lines in a module is below the threshold. ModuleNameCheck Check that module names match convention. ParameterNumberCheck Check that the number of parameters on a method is below the threshold. Friday, 28 August 2009 56
  57. 57. Roodi parameters AssignmentInConditionalCheck CaseMissingElseCheck ClassLineCountCheck 300 ClassNameCheck pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/ CyclomaticComplexityBlockCheck 4 CyclomaticComplexityMethodCheck 8 EmptyRescueBodyCheck ForLoopCheck MethodLineCountCheck 20 MethodNameCheck pattern: !ruby/regexp /^[_a-z<>=[]|+-/*`]+[_a-z0-9_<>=~@[]]*[=!?]?$/ ModuleLineCountCheck 300 ModuleNameCheck pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/ ParameterNumberCheck 5 Friday, 28 August 2009 57
  58. 58. lib/formtastic.rb:8 - Module "Formtastic" has 1272 lines. It should have 300 or less. lib/formtastic.rb:10 - Class "SemanticFormBuilder" has 1196 lines. It should have 300 or less. lib/formtastic.rb:742 - Method "date_or_datetime_input" has 33 lines. It should have 20 or less. lib/formtastic.rb:835 - Method "check_boxes_input" has 24 lines. It should have 20 or less. lib/formtastic.rb:1008 - Method "default_input_type" has 24 lines. It should have 20 or less. lib/formtastic.rb:1046 - Method "find_collection_for_column" has 27 lines. It should have 20 or less. lib/formtastic.rb:1180 - Method "localized_attribute_string" has 24 lines. It should have 20 or less. lib/formtastic.rb:742 - Method name "date_or_datetime_input" cyclomatic complexity is 10. It should be 8 or less. lib/formtastic.rb:1008 - Method name "default_input_type" cyclomatic complexity is 19. It should be 8 or less. lib/formtastic.rb:1046 - Method name "find_collection_for_column" cyclomatic complexity is 10. It should be 8 or less. lib/formtastic.rb:756 - Block cyclomatic complexity is 5. It should be 4 or less. lib/formtastic.rb:1027 - Found = in conditional. It should probably be an == lib/formtastic.rb:1103 - Found = in conditional. It should probably be an == lib/formtastic.rb:1188 - Rescue block should not be empty. lib/formtastic.rb:103 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:378 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:381 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:427 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:455 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:883 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:948 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:950 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1027 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1080 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1128 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1130 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1176 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1184 - Don't use class variables. You might want to try a different design. Friday, 28 August 2009 58
  59. 59. spec/formtastic_spec.rb:38 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:1728 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:1899 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:1900 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:2006 - Block cyclomatic complexity is 6. It should be 4 or less. spec/formtastic_spec.rb:2300 - Block cyclomatic complexity is 9. It should be 4 or less. spec/formtastic_spec.rb:2895 - Block cyclomatic complexity is 9. It should be 4 or less. spec/formtastic_spec.rb:2897 - Block cyclomatic complexity is 14. It should be 4 or less. spec/formtastic_spec.rb:109 - Case statement is missing an else clause. Friday, 28 August 2009 59
  60. 60. Let’s work through the spec first Friday, 28 August 2009 60
  61. 61. spec/formtastic_spec.rb:38 - Block cyclomatic complexity is 5. It should be 4 or less. Friday, 28 August 2009 61
  62. 62. spec/formtastic_spec.rb:109 - Case statement is missing an else clause. Friday, 28 August 2009 62
  63. 63. Existing code Post.stub!(:reflect_on_association).and_return do |column_name| case column_name when :author, :author_status mock('reflection', :options => {}, :klass => Author, :macro => :belongs_to) when :authors mock('reflection', :options => {}, :klass => Author, :macro => :has_and_belongs_to_many) end end Friday, 28 August 2009 63
  64. 64. New code def mock_post_association(column_name) return mock_association(Author, :belongs_to) if column_name.is_post_belongs_to? return mock_association(Author, :has_and_belongs_to_many) if column_name.is_post_habtm? end def mock_association(klass, multiplicity) mock('reflection', :options => {}, :klass => klass, :macro => multiplicity) end ... Post.stub!(:reflect_on_association).and_return { |column_name|mock_post_association(column_name) } Friday, 28 August 2009 64
  65. 65. spec/formtastic_spec.rb:1744 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:1915 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:1916 - Block cyclomatic complexity is 5. It should be 4 or less. spec/formtastic_spec.rb:2022 - Block cyclomatic complexity is 6. It should be 4 or less. spec/formtastic_spec.rb:2316 - Block cyclomatic complexity is 9. It should be 4 or less. spec/formtastic_spec.rb:2911 - Block cyclomatic complexity is 9. It should be 4 or less. spec/formtastic_spec.rb:2913 - Block cyclomatic complexity is 14. It should be 4 or less. Friday, 28 August 2009 65
  66. 66. Not worth addressing these Friday, 28 August 2009 66
  67. 67. Back to the non-test code Friday, 28 August 2009 67
  68. 68. lib/formtastic.rb:8 - Module "Formtastic" has 1272 lines. It should have 300 or less. lib/formtastic.rb:10 - Class "SemanticFormBuilder" has 1196 lines. It should have 300 or less. lib/formtastic.rb:742 - Method "date_or_datetime_input" has 33 lines. It should have 20 or less. lib/formtastic.rb:835 - Method "check_boxes_input" has 24 lines. It should have 20 or less. lib/formtastic.rb:1008 - Method "default_input_type" has 24 lines. It should have 20 or less. lib/formtastic.rb:1046 - Method "find_collection_for_column" has 27 lines. It should have 20 or less. lib/formtastic.rb:1180 - Method "localized_attribute_string" has 24 lines. It should have 20 or less. lib/formtastic.rb:742 - Method name "date_or_datetime_input" cyclomatic complexity is 10. It should be 8 or less. lib/formtastic.rb:1008 - Method name "default_input_type" cyclomatic complexity is 19. It should be 8 or less. lib/formtastic.rb:1046 - Method name "find_collection_for_column" cyclomatic complexity is 10. It should be 8 or less. lib/formtastic.rb:756 - Block cyclomatic complexity is 5. It should be 4 or less. lib/formtastic.rb:1027 - Found = in conditional. It should probably be an == lib/formtastic.rb:1103 - Found = in conditional. It should probably be an == lib/formtastic.rb:1188 - Rescue block should not be empty. lib/formtastic.rb:103 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:378 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:381 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:427 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:455 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:883 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:948 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:950 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1027 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1080 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1128 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1130 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1176 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1184 - Don't use class variables. You might want to try a different design. Friday, 28 August 2009 68
  69. 69. (and now I make lots of code changes) Friday, 28 August 2009 69
  70. 70. lib/formtastic.rb:115 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:390 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:393 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:439 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:467 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:926 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:991 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:993 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1045 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1126 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1175 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1177 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1223 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:1240 - Don't use class variables. You might want to try a different design. lib/formtastic.rb:20 - Module "Formtastic" has 1311 lines. It should have 300 or less. lib/formtastic.rb:22 - Class "SemanticFormBuilder" has 1235 lines. It should have 300 or less. lib/formtastic.rb:1244 - Rescue block should not be empty. Friday, 28 August 2009 70
  71. 71. and I decide that’s enough for now Friday, 28 August 2009 71
  72. 72. How does this change flog? Friday, 28 August 2009 72
  73. 73. Old and new flog warnings >88.1: SemanticFormBuilder#date_or_datetime_input 60.4: SemanticFormBuilder#inputs 60.4: SemanticFormBuilder#inputs 58.4: SemanticFormBuilder#input 58.4: SemanticFormBuilder#input 45.3: SemanticFormBuilder#database_column_input_type >57.7: SemanticFormBuilder#find_collection_for_column 43.3: SemanticFormBuilder#field_set_and_list_wrapping -56.9: SemanticFormBuilder#default_input_type 40.2: SemanticFormBuilder#radio_input >48.3: SemanticFormBuilder#localized_attribute_string 38.4: SemanticFormBuilder#localized_attribute_string -44.3: SemanticFormBuilder#check_boxes_input 31.4: 43.3: SemanticFormBuilder#field_set_and_list_wrapping SemanticFormBuilder#find_collection_for_column_explicit_or_asso 40.2: SemanticFormBuilder#radio_input ciation_or_boolean 31.2: SemanticFormBuilder#inputs_for_nested_attributes 31.2: SemanticFormBuilder#inputs_for_nested_attributes 24.0: SemanticFormBuilder#label 29.5: SemanticFormBuilder#datetime_content_tag 22.7: SemanticFormBuilder#method_required? 28.1: SemanticFormBuilder#find_collection_for_column 20.0: SemanticFormBuilder#none 26.0: SemanticFormBuilder#single_list_item_content_from 24.0: SemanticFormBuilder#label 22.7: SemanticFormBuilder#method_required? 20.2: SemanticFormBuilder#date_or_datetime_input 20.0: SemanticFormBuilder#none Friday, 28 August 2009 73
  74. 74. Changes >88.1: SemanticFormBuilder#date_or_datetime_input 45.3: SemanticFormBuilder#database_column_input_type >57.7: SemanticFormBuilder#find_collection_for_column 38.4: SemanticFormBuilder#localized_attribute_string -56.9: SemanticFormBuilder#default_input_type 31.4: >48.3: SemanticFormBuilder#localized_attribute_string SemanticFormBuilder#find_collection_for_column_explicit_ -44.3: SemanticFormBuilder#check_boxes_input or_association_or_boolean 29.5: SemanticFormBuilder#datetime_content_tag 28.1: SemanticFormBuilder#find_collection_for_column 26.0: SemanticFormBuilder#single_list_item_content_from 20.2: SemanticFormBuilder#date_or_datetime_input Friday, 28 August 2009 74
  75. 75. So what’s Flog? Friday, 28 August 2009 75
  76. 76. Confessions of a Ruby Sadist sudo gem install flog 14/08/09 3:34 AM Ruby Sadist Flog Flay Heckle Kittens About Us Confessions of a Ruby Sadist sudo gem install flog Flog shows you the most torturous code you wrote. The more painful the code, the higher the score. The higher the score, the harder it is to test. Run it against your best stuff. I double-dog dare you. So what’s Flog? Flog essentially scores an ABC metric: Assignments, Branches, Calls, with particular attention placed on calls. Run flog on all your code. Try this: find lib -name *.rb | xargs flog Whatever is at the top of the report is worth looking at. This is how it works: Friday, 28 August 2009 76
  77. 77. Confessions of a Ruby Sadist sudo gem install flog 14/08/09 3:34 AM class Test class Test def blah # 11.2 = def blah a = eval "1+1" # 1.2 + 6.0 + a = eval "1+1" if a == 2 then # 1.2 + 1.2 + if a == 2 then Is seen by 0.4 + puts "yay" flog as: puts "yay" # 1.2 end end end end end end Test#blah: (11.2) 6.0: eval 1.2: branch and reported 1.2: == as: 1.2: puts 1.2: assignment 0.4: lit_fixnum Friday, 28 August 2009 77
  78. 78. Flog weights THRESHOLD = 0.60 SCORES = Hash.new 1 # various "magic" usually used for "clever code" BRANCHING = SCORES.merge!(:alias_method => 2, [ :and, :case, :else, :if, :or, :rescue, :until, :extend => 2, :when, :while ] :include => 2, :instance_method => 2, # various non-call constructs :instance_methods => 2, OTHER_SCORES = { :method_added => 2, :alias => 2, :method_defined? => 2, :assignment => 1, :method_removed => 2, :block => 1, :method_undefined => 2, :block_pass => 1, :private_class_method => 2, :branch => 1, :private_instance_methods => 2, :lit_fixnum => 0.25, :private_method_defined? => 2, :sclass => 5, :protected_instance_methods => 2, :super => 1, :protected_method_defined? => 2, :to_proc_icky! => 10, :public_class_method => 2, :to_proc_normal => 5, :public_instance_methods => 2, :yield => 1, :public_method_defined? => 2, } :remove_method => 2, :send => 3, # eval forms :undef_method => 2) SCORES.merge!(:define_method => 5, :eval => 5, # calls I don't like and usually see being :module_eval => 5, abused :class_eval => 5, :instance_eval => 5) SCORES.merge!(:inject => 2) Friday, 28 August 2009 78
  79. 79. flog -d lib/formtastic.rb Friday, 28 August 2009 79
  80. 80. Flog details for worst method 60.4: SemanticFormBuilder#inputs 16.6: assignment 11.9: branch 11.5: to_proc_normal 5.8: block_pass 5.7: map 4.8: class 3.3: field_set_and_list_wrapping 2.3: content_columns 2.2: macro 2.1: reflections 2.0: == 2.0: to_sym 1.9: compact! 1.9: + 1.9: - 1.8: empty? 1.8: input 1.5: block_given? 1.5: inputs_for_nested_attributes 1.4: extract_options! 1.4: [] Friday, 28 August 2009 80
  81. 81. Original code def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs" if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else if @object && args.empty? args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end contents = args.map { |method| input(method.to_sym) } field_set_and_list_wrapping(html_options, contents) end end Friday, 28 August 2009 81
  82. 82. First change def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs" if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else if @object && args.empty? args = build_default_inputs_args end contents = args.map { |method| input(method.to_sym) } field_set_and_list_wrapping(html_options, contents) end end def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end Friday, 28 August 2009 82
  83. 83. Flog details 29.8: SemanticFormBuilder#build_default_inputs_args 9.0: to_proc_normal 8.7: assignment 3.8: class 3.0: map 2.9: branch 1.8: block_pass 1.8: content_columns 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: - 1.4: + 24.1: SemanticFormBuilder#inputs 8.0: branch 6.7: assignment 3.5: block_pass 3.3: field_set_and_list_wrapping 2.0: to_sym 1.8: empty? 1.8: build_default_inputs_args 1.8: input 1.7: map 1.5: inputs_for_nested_attributes 1.5: block_given? 1.4: extract_options! 1.4: [] Friday, 28 August 2009 83
  84. 84. Next change def inputs(*args, &block) html_options = args.extract_options! html_options[:class] ||= "inputs" if html_options[:for] inputs_for_nested_attributes(args, html_options, &block) elsif block_given? field_set_and_list_wrapping(html_options, &block) else contents = inputs_contents(args) field_set_and_list_wrapping(html_options, contents) end end def inputs_contents(args) if @object && args.empty? args = build_default_inputs_args end return args.map { |method| input(method.to_sym) } end def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map(&:name) args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end Friday, 28 August 2009 84
  85. 85. Flog details - only one significant method 29.8: SemanticFormBuilder#build_default_inputs_args 9.0: to_proc_normal 8.7: assignment 3.8: class 3.0: map 2.9: branch 1.8: block_pass 1.8: content_columns 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: - 1.4: + Friday, 28 August 2009 85
  86. 86. Inline to_proc def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += @object.class.content_columns.map {|c| c.name} args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end Friday, 28 August 2009 86
  87. 87. Flog details 22.4: SemanticFormBuilder#build_default_inputs_args 10.4: assignment 4.5: branch 3.8: class 3.0: map 1.8: content_columns 1.7: name 1.7: macro 1.6: reflections 1.5: == 1.4: compact! 1.4: - Friday, 28 August 2009 87
  88. 88. Extract method def build_default_inputs_args() args = @object.class.reflections.map { |n,_| n if _.macro == :belongs_to } args += content_column_names args -= %w[created_at updated_at created_on updated_on lock_version] args.compact! end def content_column_names return @object.class.content_columns.map {|c| c.name} end Friday, 28 August 2009 88
  89. 89. Flog details 16.6: SemanticFormBuilder#build_default_inputs_args 8.7: assignment 2.9: branch 1.8: class 1.7: macro 1.6: content_column_names 1.6: reflections 1.5: == 1.4: compact! 1.4: map 1.4: - 1.4: + Friday, 28 August 2009 89
  90. 90. and so forth... Friday, 28 August 2009 90
  91. 91. Other Ruby code quality tools Friday, 28 August 2009 91
  92. 92. Code churn metric Friday, 28 August 2009 92
  93. 93. Saikuro : A Cyclomatic Complexity Analyzer 14/08/09 5:05 AM Saikuro A Cyclomatic Complexity Analyzer Download Saikuro Saikuro is a Ruby cyclomatic complexity analyzer. When given Ruby source code Saikuro will generate a report listing the cyclomatic complexity of each method found. In addition, Saikuro counts the number of lines per method and can generate a listing of the number of tokens on each line of code. Version: 0.2 License Saikuro uses the BSD license. Example Output Here are examples of the output generated by Saikuro. Cyclomatic complexity summary page Token count summary page Installation As root run: # ruby setup.rb all Usage Saikuro is a command line program. Running "saikuro.rb -h" will output a usage statement describing all the various arguments you can pass to it. "saikuro -c -p tests/samples.rb" The above command is a simple example that generates a cyclomatic complexity report on the samples.rb file, using the default filter, warning and error settings. The report is saved in the current directory. A more detailed example is : Friday, 28 August 2009 "saikuro -c -t -i tests -y 0 -w 11 -e 16 -o out/" 93
  94. 94. reek, a code smells detector for ruby « silk and spinach 14/08/09 5:06 AM silk and spinach development, by example reek, a code smells detector for ruby with 23 comments To complement the imminent (ie. sometime next year) publication of the Ruby Refactoring Workbook I’ve been working on a little software tool called ‘reek’. Reek scans ruby code — either source files or in-memory Class objects — looking for some of the code smells discussed in the book. Right now it can detect (certain forms of): Long Method Large Class Feature Envy Uncommunicative Name Long Parameter List Utility Function Nested Iterators As time goes by I’ll be adding checks for more smells, and I hope to make the current checks a bit more sophisticated. But in the agile spirit of going ugly early, the current very early version is available for you to experiment with. To get the tool: gem install reek To run it: reek file1.rb file2.rb ... If you try it, please let me know what you think and what you’d like the next version to do! You can browse the reek project’s code repository at http://github.com/kevinrutherford/reek/tree/master or http://rubyforge.org/projects/reek/, both of which are clones of the same Git repository. Friday, 28 August 2009 94
  95. 95. RCov - Ruby C0 Code Coverage 15/08/09 12:11 PM RCov RCov - Ruby C0 Code Coverage Source Install $ gem install relevance-rcov Usage See the README on GitHub for the most-up to date usage of RCov. Maintained by Relevance Friday, 28 August 2009 95
  96. 96. metric fu Friday, 28 August 2009 96
  97. 97. rake metrics:all Friday, 28 August 2009 97
  98. 98. results at file:///Users/stevehayes/projects/third-party/ formtastic/tmp/metric_fu/output/index.html Friday, 28 August 2009 98
  99. 99. Java time Friday, 28 August 2009 99
  100. 100. Example code is from Apache Commons Collections 3.2.1 Friday, 28 August 2009 100
  101. 101. Simian for duplication detection Friday, 28 August 2009 101
  102. 102. java -jar simian-2.2.24.jar src/**/*.java Friday, 28 August 2009 102
  103. 103. Found 11527 duplicate lines in 871 blocks in 239 files Processed a total of 41324 significant (109875 raw) lines in 467 files Processing time: 2.404sec Friday, 28 August 2009 103
  104. 104. 27.9% of the code is duplicated Friday, 28 August 2009 104
  105. 105. Simian can also be language sensitive Friday, 28 August 2009 105
  106. 106. java -jar simian-2.2.24.jar -language=java src/**/*.java Friday, 28 August 2009 106
  107. 107. PMD for duplication detection Friday, 28 August 2009 107
  108. 108. Android Rules: These rules deal with the Android SDK, mostly related to best practices. To get better results, make sure that the auxclasspath is defined for type resolution to work. • Basic JSF rules: Rules concerning basic JSF guidelines. • Basic JSP rules: Rules concerning basic JSP guidelines. • Basic Rules: The Basic Ruleset contains a collection of good practices which everyone should follow. • Braces Rules: The Braces Ruleset contains a collection of braces rules. • Clone Implementation Rules: The Clone Implementation ruleset contains a collection of rules that find questionable usages of the clone() method. • Code Size Rules: The Code Size Ruleset contains a collection of rules that find code size related problems. • Controversial Rules: The Controversial Ruleset contains rules that, for whatever reason, are considered controversial. They are separated out here to allow people to include as they see fit via custom rulesets. This ruleset was initially created in response to discussions over UnnecessaryConstructorRule which Tom likes but most people really dislike :-) • Coupling Rules: These are rules which find instances of high or inappropriate coupling between objects and packages. • Design Rules: The Design Ruleset contains a collection of rules that find questionable designs. • Finalizer Rules: These rules deal with different problems that can occur with finalizers. • Import Statement Rules: These rules deal with different problems that can occur with a class' import statements. • J2EE Rules: These are rules for J2EE • JavaBean Rules: The JavaBeans Ruleset catches instances of bean rules not being followed. • JUnit Rules: These rules deal with different problems that can occur with JUnit tests. • Jakarta Commons Logging Rules: The Jakarta Commons Logging ruleset contains a collection of rules that find questionable usages of that framework. • Java Logging Rules: The Java Logging ruleset contains a collection of rules that find questionable usages of the logger. • Migration Rules: Contains rules about migrating from one JDK version to another. Don't use these rules directly, rather, use a wrapper ruleset such as migrating_to_13.xml. • Migration13: Contains rules for migrating to JDK 1.3 • Migration14: Contains rules for migrating to JDK 1.4 • Migration15: Contains rules for migrating to JDK 1.5 • MigratingToJava4: Contains rules for migrating to JDK 1.5 • Naming Rules: The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth. • Optimization Rules: These rules deal with different optimizations that generally apply to performance best practices. • Strict Exception Rules: These rules provide some strict guidelines about throwing and catching exceptions. • String and StringBuffer Rules: These rules deal with different problems that can occur with manipulation of the class String or StringBuffer. • Security Code Guidelines: These rules check the security guidelines from Sun, published at http://java.sun.com/security/ seccodeguide.html#gcg • Type Resolution Rules: These are rules which resolve java Class files for comparisson, as opposed to a String Friday, 28 August 2009 108
  109. 109. Basic Rules: The Basic Ruleset contains a collection of good practices which everyone should follow. • Braces Rules: The Braces Ruleset contains a collection of braces rules. • Clone Implementation Rules: The Clone Implementation ruleset contains a collection of rules that find questionable usages of the clone() method. • Code Size Rules: The Code Size Ruleset contains a collection of rules that find code size related problems. • Coupling Rules: These are rules which find instances of high or inappropriate coupling between objects and packages. • Design Rules: The Design Ruleset contains a collection of rules that find questionable designs. • Import Statement Rules: These rules deal with different problems that can occur with a class' import statements. • JUnit Rules: These rules deal with different problems that can occur with JUnit tests. • Naming Rules: The Naming Ruleset contains a collection of rules about names - too long, too short, and so forth. • Optimization Rules: These rules deal with different optimizations that generally apply to performance best practices. • Strict Exception Rules: These rules provide some strict guidelines about throwing and catching exceptions. • String and StringBuffer Rules: These rules deal with different problems that can occur with manipulation of the class String or StringBuffer. • Type Resolution Rules: These are rules which resolve java Class files for comparisson, as opposed to a String • Unused Code Rules: The Unused Code Ruleset contains a collection of rules that find unused code. Friday, 28 August 2009 109
  110. 110. Basic Rules • Empty catch block • Unnecessary final modifier • Empty if Statement • Collapsible if statements • Empty while statement • Useless overriding method • Empty try block • Class cast exception with toArray • Empty finally block • Avoid decimal literals in BigDecimal • Empty switch statements constructor • Jumbled incrementer • Useless operation on immutable • For loop should be while loop • Misplaced null check • Unnecessary conversion temporary • Unused null check in equals • Override both equals and hashcode • Avoid thread group • Double checked locking • Broken null check • Return from finally block • BigInteger instantiation • Empty synchronized block • Avoid using octal values • Unnecessary return • Avoid using hardcoded IP • Empty static initializer • Check result set • Unconditional if statement • Avoid multiple unary operators • Empty statement not in loop • Empty initializer • Boolean instantiation Friday, 28 August 2009 110
  111. 111. Basic Rules - 725 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:308 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:410 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:476 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:536 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:616 These nested if statements could be combined /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1157 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1179 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:907 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/LRUMap.java:120 These nested if statements could be combined /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MapUtils.java:170 Avoid instantiating Boolean objects; reference Boolean.TRUE or Boolean.FALSE or call Boolean.valueOf() instead. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:138 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:598 Avoid empty while statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:936 Ensure you override both equals() and hashCode() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:952 Ensure you override both equals() and hashCode() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:159 Unnecessary final modifier in final class /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:393 Unnecessary final modifier in final class /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:401 Unnecessary final modifier in final class /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:416 Unnecessary final modifier in final class /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:431 Unnecessary final modifier in final class /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/functors/PrototypeFactory.java:195 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/functors/PrototypeFactory.java:202 Avoid empty catch blocks /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterIterator.java:108 These nested if statements could be combined /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterListIterator.java:140 These nested if statements could be combined /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/FilterListIterator.java:156 These nested if statements could be combined /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:141 Avoid empty if statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:193 Avoid empty if statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/ObjectGraphIterator.java:195 Avoid empty if statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/list/CursorableLinkedList.java:428 Avoid empty if statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:278 Avoid empty while statements /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:889 Ensure you override both equals() and hashCode() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java:906 Ensure you override both equals() and hashCode() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java:133 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/HashedMap.java:96 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/IdentityMap.java:175 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LRUMap.java:395 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LinkedMap.java:117 Overriding method merely calls super /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/StaticBucketMap.java:160 Unnecessary final modifier in final class Friday, 28 August 2009 111
  112. 112. Braces Rules • If statements must use braces • While loops must use braces • If else statements must use braces • For loops must use braces Friday, 28 August 2009 112
  113. 113. Braces Rules - 210 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:268 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:600 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:476 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:272 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:280 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:370 Avoid using if...else statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:371 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:382 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:393 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:876 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:894 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:912 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:987 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1012 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1029 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:1063 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:592 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:700 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/LRUMap.java:92 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:289 Avoid using while statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:378 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:464 Avoid using if...else statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:465 Avoid using if...else statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:506 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:520 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:537 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:538 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:541 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:571 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:579 Avoid using if...else statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:580 Avoid using if...else statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:598 Avoid using while statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:621 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:622 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:665 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:711 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:771 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:778 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:779 Avoid using if statements without curly braces /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ReferenceMap.java:780 Avoid using if statements without curly braces Friday, 28 August 2009 113
  114. 114. Clone Rules • Proper clone implementation (should include super.clone()) • Clone throws CloneNotSupportedException • Clone method must implement cloneable Friday, 28 August 2009 114
  115. 115. Clone Rules - 25 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 Object clone() should be implemented with super.clone() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:281 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 Object clone() should be implemented with super.clone() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:419 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 Object clone() should be implemented with super.clone() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:470 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:464 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/MultiHashMap.java:464 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractHashedMap.java:1227 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/AbstractHashedMap.java:1227 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java:133 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/Flat3Map.java:1014 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/HashedMap.java:96 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/IdentityMap.java:175 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LRUMap.java:395 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/LinkedMap.java:117 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 Object clone() should be implemented with super.clone() /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 clone() method should be implemented only if implementing Cloneable interface /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiKeyMap.java:818 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/SingletonMap.java:538 clone() method should throw CloneNotSupportedException /Users/stevehayes/commons-collections-3.2.1-src/src/test/org/apache/commons/collections/BulkTest.java:177 clone() method should throw CloneNotSupportedException Friday, 28 August 2009 115
  116. 116. Code Size Rules • NPath complexity (200) • Excessive method length (100) • Excessive parameter list (10) • Excessive class length (1000) • Cyclomatic complexity (10) • Excessive public count (45) • Too many fields (15) • NCSS method count (100) • NCSS type count (1500) • NCSS constructor count (100) • Too many methods (10) Friday, 28 August 2009 116
  117. 117. Code Size Rules - 338 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:55 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:63 The class 'BinaryHeap' has a Cyclomatic Complexity of 2 (Highest = 14). /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:64 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:465 The method 'iterator' has a Cyclomatic Complexity of 14. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BinaryHeap.java:482 The method 'remove' has a Cyclomatic Complexity of 10. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BoundedFifoBuffer.java:56 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ClosureUtils.java:57 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:17 his class has a bunch of public methods and attributes T /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 void really long classes. A /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 he class 'CollectionUtils' has a Cyclomatic Complexity of 3 T (Highest = 14). /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:58 his class has too many methods, consider refactoring it. T /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:741 The method 'index' has a Cyclomatic Complexity of 13. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:829 The method 'get' has a Cyclomatic Complexity of 14. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CollectionUtils.java:894 The method 'size' has a Cyclomatic Complexity of 10. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ComparatorUtils.java:44 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:17 This class has a bunch of public methods and attributes /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:55 Avoid really long classes. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:55 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:1202 his class has too many methods, consider refactoring it. T /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/CursorableLinkedList.java:1405 he method insertListable() has an NPath complexity of T 200 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DefaultMapBag.java:48 his class has too many methods, consider refactoring it. T /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:17 This class has a bunch of public methods and attributes /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 Avoid really long classes. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 The class 'DoubleOrderedMap' has a Cyclomatic Complexity of 4 (Highest = 15). /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:107 This class has too many methods, consider refactoring it. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:202 The method 'entrySetByValue' has a Cyclomatic Complexity of 12. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:341 The method 'valuesByValue' has a Cyclomatic Complexity of 11. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:804 The method 'doRedBlackInsert' has a Cyclomatic Complexity of 11. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:875 The method 'doRedBlackDelete' has a Cyclomatic Complexity of 13. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:952 The method 'doRedBlackDeleteFixup' has a Cyclomatic Complexity of 12. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/DoubleOrderedMap.java:1044 The method 'swapPosition' has a Cyclomatic Complexity of Friday, 28 August 2009 117
  118. 118. Coupling Rules • Coupling between objects (attributes, local variables, return types) (20) • Excessive imports (30) • Loose coupling (avoid using implementation types, use interface instead) Friday, 28 August 2009 118
  119. 119. Coupling Rules - 63 /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:59 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:60 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:61 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/BeanMap.java:72 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:187 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1037 Avoid using implementation types like 'Vector'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1053 Avoid using implementation types like 'Vector'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/ExtendedProperties.java:1053 Avoid using implementation types like 'Vector'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastArrayList.java:117 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastHashMap.java:71 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/FastTreeMap.java:73 Avoid using implementation types like 'TreeMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/IteratorUtils.java:17 A high number of imports can indicate a high degree of coupling within an object. /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/SequencedHashMap.java:154 Avoid using implementation types like 'HashMap'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/StaticBucketMap.java:508 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:49 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:52 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/iterators/CollatingIterator.java:361 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiValueMap.java:78 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/MultiValueMap.java:109 Avoid using implementation types like 'ArrayList'; use the interface instead /Users/stevehayes/commons-collections-3.2.1-src/src/java/org/apache/commons/collections/map/StaticBucketMap.java:499 Avoid using implementation types like 'ArrayList'; use the interface instead Friday, 28 August 2009 119
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×