8

In a project using spring reactor, we have detected that the real complexity of the reactive code is not detected by our static analysis tools. At the moment we are using a combination of PMD, Checkstyle, Spotbugs and SonarQube, but none of them is able to detect "complex reactive code".

Is there any other tool out there that can take into account the new reactive and stream APIs in Java?

Just some very simple examples that are considered to have cyclomatic complexity 0 could be:

  // EXAMPLE 1: Optional usage for avoiding null field checks
  int activeSensors = Optional.of(sensorData).map(SensorData::getActiveCount).orElse(0);

  // EXAMPLE 2: Stream API usage for replacing iterations and conditionals
  list.stream().filter(Objects::nonNull).forEach(item -> do_something(item));

  // EXAMPLE 3: Reactive API
  Flux<Float> historyValuesFlux = Mono.justOrEmpty(sensorData)
      .filter(Objects::nonNull)
      .flatMapMany(data -> Flux.fromIterable(data.getHistoryPoints()))
      .filter(Objects::nonNull)
      .map(SensorHistoryPoint::getValue);

In the three cases, the "classic equivalent" code has a higher complexity value, so our concern is that the actual complexity of the code is being hidden by the new syntaxis. And this means that our estimations of the code mantainability are wrong, and they will worsen with time.

Nodens2k
  • 161
  • 6
  • 2
    I'd argue that this code is, in fact, significantly less complex to read than "classical" code. Creating this in the classical way would result in a nasty forest of for loops and ifs, but this is pretty easy to follow. – Sebastian Lenartowicz Jan 09 '20 at 15:17
  • 2
    @SebastianLenartowicz That doesn't help measure complexity. In any case, I've had a go at rewriting those examples in classic style, and they're much more understandable. They'd be even more understandable if they didn't use nulls. There's rarely much advantage in stream style, and reactive seems to be about moving state from stack to heap (fibres look like they may make that pointless in future as far as I can work out). / So, counting the use of streams/reactive libraries is a good way of measuring this particular accidental complexity. – Tom Hawtin - tackline Jan 09 '20 at 15:56
  • 2
    @TomHawtin-tackline that’s a great indicator that cyclomatic complexity is not the same as readability or understandability. – Holger Jan 09 '20 at 16:16
  • 1
    Well, apart from readability, there are other aspects that get impacted by code complexity, as the testing effort requirements and the risk of having defects. For us, these two points are the main reasons for having code complexity under control. However, we are entering into the subjective area here. The relevance of code complexity is not the same for everybody, after all. – Nodens2k Jan 10 '20 at 08:36
  • 4
    Cyclomatic complexity is a metric of the *source code*, not of what invoked methods may do behind the scenes. Yes, this implies that breaking source code into smaller units, hiding complexity *is* a way to solve the issue of high complexity. So `list.forEach(System.out::println)` *has* lower complexity than `for(Object o: list) System.out.println(o);`. Don’t confuse with computational complexity or “what does this code actually do”, as when you refactor the code to make it more maintainable, you don’t change the purpose of the code, i.e. in my example, a linear iteration is unavoidable. – Holger Jan 10 '20 at 12:03
  • @Holger, you are right. Computational and cyclomatic complexities are different concepts. I guess we are looking for a way to measure the computational complexity here, with the "calculation scope" restricted to isolated methods. I don't know if there is any tool that can do something like this in the market, but probably there are not. – Nodens2k Jul 28 '20 at 10:24
  • I am afraid that this question is not a good fit for SO because it is asking to recommend a software. However maybe the question about how cyclomatic complexity should be affected by streams / functional programming might be relevant – or maybe better for [softwareengineering.se]? – Didier L Nov 06 '20 at 10:07

0 Answers0