Saturday, October 26, 2013

Too Many Parameters in Java Methods, Part 8: Tooling

The first seven posts of my series of dealing with too many parameters expected in Java methods focused on alternative approaches to reduce the number of parameters a method or constructor expects. In this eighth post in the series, I look at tools that help identify cases where too many parameters may exist and tools that help deal with that when it occurs.

There is really no hard rule for the number of parameters to a method or constructor that is too many. In many ways, it's a matter of taste and depends somewhat on what those parameters are, if they use custom types rather than primitives and repeated types, and whether there are optional parameters that might require null to be passed.

Robert Martin, in Clean Code, writes (page 40):

The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification - and then shouldn't be used anyway.

Steve McConnell, in Code Complete, writes that developers should "limit the number of a routine's parameters to about seven" because "seven is a magic number for people's comprehension." I don't think there's any set maximum number of parameters, but seven does seem like a "rule of thumb" to rarely exceed and I do generally prefer a smaller number such as Martin's recommendation of fewer than three arguments.

"The Eye Test"

There is a common expression in sports talk and sports writing that some player or team "doesn't pass the eye test." My understanding of that expression is that it means that despite whatever positive statistics might be associated with that player or team, watching the player or team play leads one to believe that they are not as good as the statistics might indicate. In other words, in a way that is difficult to describe, the viewer feels the team or player is not as skilled as their statistics imply.

In many ways, software development has its own "eye tests" that tell us when certain things are better or worse than the "rules" imply. Despite this, we still have "rules" or general guidelines about what makes for a generally good software practice just as sports have statistics to attempt to contrast teams and players objectively. For example, in software, we might say that "fewer parameters is generally better than more parameters." Tooling's biggest limitation is that it cannot perform an "eye test" for us, but it can help us to identify potential areas for improvement. In other words, tooling can help report the "statistics" of the game or match, but we must pass our own judgment ("eye test") on what the tooling is reporting.

Static Analysis Tools

Static analysis tools can be used to automatically identify methods or constructors which might expect too many parameters. Once the methods and constructors with potentially too many parameters have been identified, the developer can apply the "eye test" to them to determine if corrective action should be taken.

PMD

PMD (with the humorous slogan "Don't Shoot the Messenger") is a "source code analyzer" that "finds common programming flaws" in a number of programming languages (including Java). One of PMD's rules is "ExcessiveParameterList" (LongParameterListRule in PMD 4.3 instead of ExcessiveParameterList). The PMD-provided action when this rule is triggered is to "try to group the parameters together" with a "a new object [that] should be created to wrap the numerous parameters" (see my post on parameters objects). Newer PMD documentation puts it this way, "Methods with numerous parameters are a challenge to maintain, especially if most of them share the same datatype. These situations usually denote the need for new objects to wrap the numerous parameters."

Any tool must have a specified number of parameters that is considered "too many." In PMD's case, that default number is 10. Note that this default minimum threshold for triggering the PMD rule is higher than Steve McConnell's recommendation of 7 maximum parameters and significantly higher than Robert Martin's recommendation of fewer than three parameters.

NetBeans PMD support is available via the PMD Plugin. NetBeans PMD support is also available via the Software Quality Environment Plugins. I covered this in the previous posts NetBeans 7 and Software Quality Environment and Configuring SQE Plugins in NetBeans 7. QAPlug-PMD is a similar plug-in for IntelliJ IDEA and PMD Eclipse is available for Eclipse.

Checkstyle

Like PMD, Checkstyle detects and warns about too many method and constructor parameters. Checkstyle is defined on its main web page as "a development tool to help programmers write Java code that adheres to a coding standard." Specifically, Checkstyle provides the ParameterNumber "check" with the description, "Checks the number of parameters of a method or constructor." In Checkstyle's case, the default "maximum allowable number of parameters" for a constructor or method is 7 (same number as Steve McConnell's recommendation).

Checkstyle can be used in conjunction with NetBeans using the Checkstyle Beans plugin. Like NetBeans PMD support, Checkstyle support in NetBeans is also available via the previously mentioned Software Quality Environment. The eclipse-cs plugin supports Checkstyle integration with Eclipse and Checkstyle-IDEA is a similar plugin for IntelliJ IDEA.

CodePro Analytix

CodePro Analytix is part of the Google Java Developer Tools and is described as "the premier Java software testing tool for Eclipse developers who are concerned about improving software quality and reducing developments costs and schedules." It includes Code Audit capabilities with one category of rules being "Program Complexity." One of these rules is the "Large Number of Parameters" rule. That rule's Summary is that "Methods should not have too many parameters" and its description is: "This audit rule finds methods that have more than the specified number of parameters. Methods that exceed this number are likely to be too complex. Consider moving some of the values and behavior associated with them into a separate class."

It is also worth noting that CodePro Analytix also supports a "Average Number of Parameters" metric for metrics reporting. This metric reports the average number of parameters per method, but does not include constructors.

NetBeans Java Code Metrics Hints

I've already mentioned NetBeans plug-ins for Checkstyle and PMD, but one of my favorite features in NetBeans is the numerous and highly customizable built-in NetBeans hints and inspections. NetBeans 7.4 introduces a whole new category of hints called "Java Code Metrics" and one of these new hints is the "Constructor declares too many parameters" hint. This hint is described as, "Reports constructor that take too many parameters. Constructors typically take more parameters than a regular method, especially when initializing a large object. Large number of parameters indicate a bad design. It's likely that yet more parameters will be added in the future, so creational patterns like Builder should be considered." I covered the application of the builder pattern and even discussed using NetBeans to refactor a builder in a previous post in this series.

Another newly added hint, "Method declares too many parameters," is described as, "Reports method that take too many parameters. Methods with large number of parameters indicate a bad design. It's likely that yet more parameters will be added in the future, so the parameters should be grouped into a Command Object, improving maintenance costs. Alternatively, the method could be refactored into several methods, each doing part of the task and requiring less parameters at input." This recommended approach is essentially the same as the parameters object approach I blogged about earlier in this series of posts.

All of the hints in the "Java Code Metrics" category of NetBeans 7.4 are disabled by default. In his blog post "Just How Messed Up Is My Code?," the "occasional" NetBeans blogger Geertjan Wielenga demonstrates how to configure the Java Code Metrics to be active.

The next screen snapshot demonstrates use of Java Code Metrics in NetBeans 7.4. This is configured by selecting "Source" followed by "Inspect..." (which will open the NetBeans 7.4 "Inspect" window)

When the drop-down next to the "Use" label and "Configuration" bullet is selected in the "Inspect" window, the choices indicated in the next screen snapshots are available.

For my demonstration purposes, I select "All Analyzes" and then click on the "Inspect" button. The next screen snapshot demonstrates the inspection/analysis in progress.

"Out of the box," the NetBeans Inspect mechanism finds a bunch of my code missing Javadoc statements, but does not flag the constructors and methods with too many parameters. To address this, I need to follow the steps in Geertjan's blog post. To do this, I can click on the Source | Inspect and select "Default" for "Configuration."

Selecting "Default" allows me to now click on the "Manage..." button and clicking on that button presents the "Configuration" window.

Clicking on the "Default" label leads to a drop-down from which "New..." can be selected.

I can name the new configuration "Java Code Metrics".

Clicking on the drop-down next to the "Analyzer" label allows me to select "NetBeans Java Hints" and selecting that option presents all of the NetBeans Java Hint by categories. The next screen snapshot shows that I can select the code metrics to be inspected.

The next screen snapshot indicates that I can select "Constructor declares too many parameters" as a checkbox and "Method declares too many parameters" as another checkbox.

With a new "Java Code Metrics" inspection, it is easy to now inspect for those particular concerns by clicking on the "Inspect" button.

Pressing "Inspect" to apply the newly created "Java Code Metrics" inspection, leads to results shown in the following screen snapshots. The first image shows the high-level results and following images show more specific details made available by clicking on the high-level results.

With all of the static analysis tools I've covered, one can adjust the number of parameters deemed "too many" for a constructor or method. This configuration is really easy with NetBeans's Java Code Metrics support. The next two screen snapshots demonstrate that these values are set for constructors and methods respectively in the same window where we checked the options we wanted inspected. The expanded window for each checked option includes definition of the inspection type and a field to select the applicable number of parameters.

It is nice to be able to easily change the number of parameters deemed unacceptable (or at least worth pointing out so that the "eye test" can be applied) because there is such widely differing opinions on what number is unacceptable.

As the last series of screen snapshots demonstrate, NetBeans 7.4 allows us to specifically inspect code for methods and constructors that have "too many parameters." As I have been writing this portion of this post, I'm reminded that NetBeans provides significant static code analysis support.

IntelliJ IDEA Inspections

IntelliJ IDEA provides inspections for ferreting out methods with too many parameters. The "Method with too many parameters" inspection is described as: "This inspection reports any instances of methods with too many parameters. Methods with too many parameters are a good sign that refactoring is necessary. Methods whose signatures are inherited from library classes are ignored by this inspection." This inspection allows the number of method parameters that is too many to be configured.

Other Static Analysis Tools

There are other tools besides the ones that I have already focused on that, through static analysis, identify and flag awhen a Java method or constructor accepts "too many parameters." These include Java Coding Standard Checker and Sonar. The existence of all these static analysis tools that identify "too many parameters" is evidence that having too many parameters can be a maintenance and readability problem.

Code Change Tools

The tools discussed so far in this post have been useful in analyzing code to find existing methods and constructors expecting too many parameters. Once identified, these constructors and methods can be manually changed/refactored to reduce the number of parameters with approaches such as the ones I've outlined in earlier posts in this series of too many parameters. Fortunately, there are some tools that can aid in these refactoring and new code generation efforts. Modern Java IDEs are particularly helpful in the refactoring and code generation efforts.

Refactoring

One of the my favorite approaches for dealing with too many parameters to a constructor is application of a builder. Fortunately, NetBeans provides the ability to automatically refactor code relying on numerous parameter constructor to use a builder implementation. I have blogged on this approach previously in posts Too Many Parameters in Java Methods, Part 3: Builder Pattern and NetBeans 7.2: Refactoring Parameterized Constructor As Builder. IntelliJ IDEA has a similar refactoring tool called Replace Constructor with Builder. The Builder Pattern Eclipse Plugin is available for Eclipse.

Code Generation

Some of my favorite approaches for dealing with too many parameters include writing new custom types and creating parameters objects. Modern Java IDEs are tremendous here, making generation of these classes and enums simple. It often takes only a few minutes to generate a complete class with appropriate toString(), hashCode(), and equals(Object) implementations. It's really difficult for one to argue that it's too "expensive" to write custom type classes and parameters object (command) classes given how easy they are to write with modern Java IDEs and their code generation capabilities.

Conclusion

The focus of this post has been on tools that are available to the Java developer for identifying places in Java code where methods and/or constructors expect too many parameters and on tools available for easily fixing these constructors and methods to accept a more reasonable number of parameters. There are several static analysis tools and IDEs that support rapid identification of constructors and methods that expect too many parameters and modern Java IDEs make refactoring and code generation quick and easy. The wide number of tools available for identifying the "too many parameters" issue is a reminder that this is in fact an issue worth fixing.

1 comment:

Ramon Casha said...

A related article on named parameters in Java. Rather than have loads of parameters to cover all possible permutations, let the user supply only those parameters that are needed:

http://zinzel.blogspot.com/2010/07/creating-methods-with-named-parameters.html