I'm not ashamed to admit that I feel scared and creepy when I see complex blocks of code. In fact, I can tell you that you're a little bit creepy when you run into a lot of methods and messy, sprawling classes. It cannot be said that those who seek refuge in these circumstances are not perfect, and this is an instinct of good developers. Overly complex code is difficult to test and maintain, which usually means a higher error rate.
I have explained the cyclomatic complexity in previous articles in this series, which is a precursor to annoying code. Test methods with high cyclomatic complexity values almost always make a mess of things that can't be easily ended. For the last one months, I've shown you how to refactor your code using the Extract method mode to take you out of the maze. Reducing the complexity of the method makes the code easier to test and maintain, as shown in Figure 1:
Figure 1. Reduce complexity to make code easier to maintain and test
However, cyclomatic complexity is not the only measure of complexity that determines high risk code. You can also take advantage of class length, method length, and inner class coupling. There is an intricate correlation between these metrics, but these associations are easy to spot. This month, I will explain why they are so important and how to use PMD and JavaNCSS to track them.
There are too many codes!
It is important to understand the difference between simple code and fluent code. Simple code does not have to be too simple or easy to write, just easy to understand. You can write simple code in C + +, just as you would write them with Visual Basic. However, the quickest way to reverse code in any language is to write a lot of code at once.
Consider how to apply this rule to methods and classes. A simple reason most people have a headache remembering credit card numbers is that we can only manage 7 (±2) data at a time. With this in mind, it becomes clear that too many conditions can cause trouble in the future, making testing and maintenance difficult. The same principle can also be applied to logical blocks.
All the given code bodies typically contain grouped statements that have common goals, such as creating a collection and adding data items to the collection. However, grouping a large number of logical blocks in a long method (long methods) can quickly forget the overall intent of the method, because few people can effectively handle such a large dataset. This is precisely the flaw that has brought maintenance issues in the code base. The lengthy approach is a flawed haven, as few people can effectively analyze them. The long way not only completes too many work, also needs the people to have the very big effort to understand!
Just as long as a way of making developers hate it, long classes can also be annoying to developers. The same discussion can be applied to the overall code, and a lengthy class can do too much work and take on too much responsibility.
What's too long?
Of course, the long method or the division of the class is somewhat subjective. There is a very helpful rule of thumb, and you can say that a method that is more than 100 lines in a code comment line is a long method. However, the actual value varies according to the person who is talking about it. As far as I'm concerned, the cutoff point is about 50 lines of code, but some developers will say that it's too long if a method requires you to scroll down a whole day to read it. Cutoff The definition of the cutoff point depends on you.
Similarly, you must have your own good judgment of determining the correct class size. A rule of thumb advocated by many people is that a class with more than 1,000 lines of code can say that the class is too long. Others think it is best not to exceed 500 lines of code.
Internal class coupling
For a relationship between an object and another object, the complex pattern repeats itself continuously. Classes that import many external dependencies or have many public methods are difficult to understand, and the increased burden of responsibility can lead to some kind of fragility.
I'll start with the dependencies. If an object imports more than 80 external classes (excluding the normal Java™ system library), it can be said that the class has high output coupling, which means that changing the imported class might affect the class itself. In the worst case, if you import a specific class and their behavior changes, the class that performs the import may break!
Observing the number of object imports is easy to predict vulnerability, but if you use a. * symbol (such as com.acme.user.*) to import the entire package, it is likely to be misleading. For more precise purposes, it may be necessary to note the number of unique types that an object has (which can be obtained by parsing code-not an import statement). A unique type metric (types metric) can be helpful if your application's package structure is roughly designed in a way that contains many classes in a few packages.
Classes that contain many public methods also have many imports. These classes usually become the center of the code base, just like facades or tool classes. Because of this responsibility (exported through a large number of public methods), they have high input coupling and can also cause reverse vulnerability. If any of these classes change, a variety of seemingly unrelated application parts may break.