In your experience, what is a useful rule of thumb for how many lines of code are too many for one class in Java?
To be clear, I know that number of lines is not even close to the real standard to use for what should be in a particular class and what shouldn’t. Classes should be designed according to proper OOP philosophies (encapsulation, etc.) in mind. That said, a rule of thumb could provide a useful starting point for refactoring considerations (i.e. “Hmmm, this class has >n lines of code; it’s probably unreadable and doing a lousy job of encapsulation, so I might want to see if it should be refactored at some point”).
On the flip side, perhaps have you encountered examples of very large classes that still obeyed OOP design well and were readable and maintainable despite their length?
Here’s a related, non-duplicate question about lines per function.
For me, lines of code is irrelevant in this context. It’s all about the number of different reasons I would come to this class to change it.
If I would come to this class when I want to change the rules for validating a Person, I don’t want to come to the same class to change the rules for validating an Order, nor do I want to come here to change where I persist a Person.
That said, if you aim for that then you will rarely find classes more than 200 lines. They will happen, for valid reasons, but they’ll be rare. So if you’re looking for a red-flag metric then that’s not a bad place to start; but make it a guideline, not a rule.
Some interesting metrics:
junit fitnesse testNG tam jdepend ant tomcat ----- -------- ------ --- ------- --- ------max 500 498 1450 355 668 2168 5457mean 64.0 77.6 62.7 95.3 128.8 215.9 261.6min 4 6 4 10 20 3 12sigma 75 76 110 78 129 261 369files 90 632 1152 69 55 954 1468total lines 5756 49063 72273 6575 7085 206001 384026
I use FitNesse as a benchmark because I had a lot to do with writing it. In FitNesse the average class is 77 lines long. None are longer than 498 lines. And the standard deviation is 76 lines. That means that the vast majority of classes are less than 150 lines. Even Tomcat, that has one class in excess of 5000 lines, has most classes less than 500 lines.
Given this we can probably use 200 lines as a good guideline to stay below.
It depends on the complexity, not the number of lines. I’ve written big dumb routines that were easy to understand and which did precisely one thing and did it well, but went on for hundreds of lines. I’ve written fairly short functions that were hard to understand (and debug).
Another thing you could look at is the number of public functions in a class. That can also be a warning sign.
I don’t have good counts available, but I’d suggest looking at some decent code that does useful things at your shop, and basing it off that. Certainly you should look at the longest classes and the biggest APIs.
There are too many lines of code if the class is doing too many different things. Essentially, if you follow the principle of Single Responsibility for classes, there is a limit to how large the class will grow.
As to physical limitations you can have (source: Class file format Java5):
- 65,536 constants, interfaces applied, fields, methods, and attributes–each. NOTE: you will run out of constant space before you run out of any of the other items. NOTE 2: attributes are class file constructs–not to be confused with ‘@Attribute’ markers (i.e. debug info and byte code are stored as separate attributes for a method).
- Each method can be 4GB (32 bits) of generated byte code. NOTE: Java versions prior to 1.5 could only have 64KB (16 bits) of generated byte code for each method.
In short, the class file can be much larger than anyone would consider useful. If you stick to the single responsibility principle, your class files will be the right size.
The correct answer is 42. Just kidding.
Actually, the maximum recommended lines per class is 2000 lines.
“Java Code Conventions” since 1999 have stated it this way:
Files longer than 2000 lines are cumbersome and should be avoided.
Having followed Sun/Oracle Coding conventions since Java was invented,
I’ve found this rule of thumb on lines per class to be reasonable.
99% of your Java Code should conform… And if it goes over 2000,
just put a TODO at the top saying the class needs work.
The worst thing is the opposite case when programmers create too many tiny
little classes with almost no real functionality in each class. Ignoring the advice to “Favor Composition”, programmers create hundreds of inheriting classes which create complicated object models that are far worse than the large class problem (which at least usually keep functionality with a relevant class name).
I’m sorry but I’m very surprised that many answers state that it “doesn’t really matter”. It very MUCH matters how many lines are in a class. Why? Consider these principles in writing good Java code…
Classes with lots of lines in them will most likely violate all of those principles.
For those who have stated it “doesn’t really matter”…how much fun has it been for you to try and understand a class that has 5000+ lines in it? Or, to modify it? If you say that’s fun, you’ve got a strange affinity towards pain…
I would say any class that has greater than 1000 lines in it should at least be questioned in how they may be violating the principles above and possibly parsed out into several “off-shoot” classes.
My comments are based off of reading and studying such authors as Martin Fowler, Joshua Bloch and Misko Hevery. They are excellent resources to consult for writing good Java code.
Do the next guy (which could be you in a couple of years) a favor and strive to write classes that have fewer rather than more lines in them.
Try using a better metric.
One example is the ABC Metric. It is more a measure of how much work is being done by the code than how much code there is.
Any line that falls within your class’s problem domain written outside of the class is one line too few and one too many in the class where it lives. Think of a class as a topic. You have to cover it. As concisely as possible is ideal but if it takes 500 lines, it takes 500 lines. If 100 of those lines cover another topic, they belong somewhere else. Breaking into smaller subdomains within the class as interior classes makes sense but I would only define those outside of the class if they had use elsewhere.
Number of lines is a pretty poor metric for class quality. For me, I like to look (as others have mentioned) at public methods, as well as any publicly exposed properties (I guess public getters/setters in Java). If I had to pull a number out of the air for when it might catch my attention, I would say when there are more than 10 of each. Really, if its more than about 5 of either properties or methods, I will take a look and often find ways to refactor, but anything over 10 is usually a warning sign that something is fairly likely to be poorly exposed.
Its another conversation entirely, but private methods and fields are less of a smell for me, so if they are contributing a lot to the number of lines, then I might not be as worried. At the very least, it shows that there probably is not some God controller maniplating the object from afar, which is a pretty problem design problem.
Classes Should Be Small!
The first rule of classes is that they should be small. The second rule of classes is that they should be
smaller than that. No, we’re not going to repeat the exact same text
from the Functions chapter. But as with functions, smaller is the
primary rule when it comes to designing classes. As with functions,
our immediate question is always “How small?”
** With functions we measured size by counting physical lines. With classes we use a different measure. We count responsibilities.**
The name of a class should describe what responsibilities it fulfills. In fact, naming
is probably the first way of helping determine class size. If we cannot derive a concise
name for a class, then it’s likely too large. The more ambiguous the class name, the more
likely it has too many responsibilities. For example, class names including weasel words
like Processor or Manager or Super often hint at unfortunate aggregation of
- Just make sure your methods do only one thing.
- Then make sure the class doesn’t have too many responsabilities.
You will end up with a class of an manageable size.