Java: Complexity Measurement
There are several approaches to estimating how much complexity humans will perceive in a program. Many of these techniques are applied to single methods, some to classes, and some to entire programs.
Some of these measures can be automated, but it's unlikely that complexity measurement software will ever accurately model the human difficulties in comprehending source code, not to mention that there are lots of individual programmer differences.
- Visual size. Common advice is that a method that's larger than "a page" should be broken up. Although laughably gross, this measurement provides a very good rule of thumb.
- Lines of code is another complexity measurement. Ignore comments and declarations when counting. You may see various acronyms for this such as LOC (Lines Of Code), SLOC (Source Lines Of Code), or NCSL (Non-Commented Source Lines).
- The number of operators and operands in a method/program is one measure of complexity, and Halstead proposed a number of measures based on operators and operands. This hasn't turned out to be as useful as expected however.
- Span complexity is a measurement of the distance between references to a variable. A larger span creates more short-term memory requirement. This seems more useful as a general coding guideline when writing a method than as a numerical measurement. This supports the declare-at-first-use practice for local variables.
- Nesting depth is a measure of complexity in a method. Less deep code is easier to read. Again, this is useful as a coding guideline.
- Coupling is the amount by which several modules (eg, classes) depend on others. The lower the coupling the better. There are several schemes for this, counting the number of methods that are called, number of classes that are referenced, coupling through parameters and globals, etc. A nice illustration of how this can be automated is Headway Software's Structure101, which I haven't used because of the high price, but there's a nice online demo that shows program visualizations at many different levels.
- Flow complexity is a very important part of the total complexity of a method.
There are two common measurements of flow complexity
- McCabe's Cyclomatic Complexity measurement is essentially a count of how many places the flow branches.
- Nejmah's NPATH complexity counts all possible execution paths through a method.
-
Structured Programming. Simplifying control flow was the prime motivation for
Structured Programming, which can be
summarized most simply, but not especially comprehensibly,
as the elimination of the
goto
statement. The ideals of structured programming have been so completely incorporated in modern programming that some newer languages, eg Java, don't even have thegoto
statement. The Java designers must have thought leaving outgoto
was risky becausegoto
is still reserved as a keyword, but is not used. - Function points are measurements of complexity in the design phase. From design information one can estimate the number of function points. The number of function points can the be used to estimate the size, effort, or schedule. See Function Point Analysis: Introduction for more information on this. This is not a technique which is useful for typical student programs, but it is very useful for programs that interact with databases.