When is a function too long? is a subset of this question, I think.
What are a few good metrics for determining that a class is too long?
I'm rerevising a set of code acceptance guidelines for a project with external contractors, and realized I haven't covered this in the past, but should cover this in the future.
When it has more than one responsibility.
Let me quote Robert C. Martin's Clean Code here:
The first rule of classes is that they should be small. The second
rule of classes is that they should be smaller than that. ... With
functions we measured size by counting physical lines. With classes we
use a different measure. We count responsibilities. [Chapter 10, page 136]
Class fan-out complexity: The number of other classes a given class relies on. Also the square of this has been shown to indicate the amount of maintenence required in functional programs (on a file basis) at least.
Cyclomatic complexity: Checks cyclomatic complexity against a specified limit. The complexity is measured by the number of if, while, do, for, ?:, catch, switch, case statements, and operators && and || (plus one) in the body of a constructor, method, static initializer, or instance initializer. It is a measure of the minimum number of possible paths through the source and therefore the number of required tests. Generally 1-4 is considered good, 5-7 ok, 8-10 consider re-factoring, and 11+ re-factor now!
No more than 17 lines. No more, no less. So if is under 17 lines carriage returns will do the trick. If its more than 17 you will need to start calling other functions from within the function.
For example:
public function myFunction() {
...
line 17: myFunctionPart2();
}
public function myFunctionPart2() {
...
line 17: myFunctionPart3();
}
And so on.
Its pretty standard programming practice.
One class should have only one responsibility. That is a better measure than its length. So, when designing your code, every unit of your design (a type or a class) should be responsible for only one thing (whatever "one thing" is in your case).
If you keep it as simple as possible, you won't get in a mess.
Ignoring the design pattern in use, I would consider the scope of responsibility the class fulfills. If the scope is too large, it should be broken up into specific responsibilities, abstracted away, or made more generic.
I wouldn't actually take the number of lines as a meaningful metric.
When you think that now it has become harder for you to manage it and gets you stuck.