Hi.
I recommend that you do not worry too much about code metrics such as line numbers in itself, but much more what the lines are doing. And this is obvious.
A nice guideline that I've heard is, when you are nesting three brackets down, such as:
public void method() {
nest-1
{
nest-2
{
/* Code that gets not only repeated, but refactored often since
it's an important part of the system. You are more likely to change
this section of the code, than the loop header. Therefore, if this
becomes a function, your concentration could be centered there without
distractions.
*/
}
}
}
then the code in "nest-2" could be refactored to be a function. "Nest" in this context could be anything, such as an anonymous function, a loop or anything that will re-indent you specification code.
Advantage is more-readable code, but watch out when using threads in UI development (talking in .NET and probably some others) where you should know which threads are calling which methods. We all hate nasty cross thread exceptions.
A metric for a method is for it to have a single and unique purpose in the system. This is again, as many others have said on this question, the DRY principle (Don't Repeat Yourself, if you haven't picked up a copy of 'The Pragmatic Programmer', I highly recommend it).
I won't say any numbers, such as limits, as they are matter of preference. 'Don't be a slave to formal methods' is what programmers refer to this issue sometimes. And simply, some programmers will give you different numbers and this will leave you not confused, but disappointed. That is their preference and their choice to which to they agree to stick to. And good, since everyone has got a style that defines their unique code tailoring skills.
Horizontally, I would try keep a limit. I believe that horizontally, decently-short code is the most enjoyable to read: I would like to hear what other people think. What sometimes bothers me is that some variables
need a long name to distinguish themselves and name their true purpose, and this lengthens the line of code when a complex expression is required.
I would also avoid things like
var myVar = MyObject.ItsMethodThatReturnsAnObject().ThatSecondObjectsMethod();
That is a different type of nesting, where you can incur into many troubles I'll leave up to you to understand. 'Un-nest' this by giving MyObject an appropriate method that does the extra check.
Regarding the lines per function, I would first look at my spec document. What are the tasks of the software? They could all be a function, but at code time, dozens of mini-functions appear - this is why coding is not just a mechanical process in which a design is implemented, but is further design of your already existing sketch.
When you have a block of code that does A, B and then maybe C. Then to finalize and clean the return value it performs D. Sometimes it doesn't. Sometimes we put big comments on top of a block of code to describe what it's doing. Then another section. They do different things and deal with different variables. - To the thinking programmer this would pop up: "Those variables are visible in that other section, but that section should not just never see them, but never need them.". Separate that code into a function which will only ever see the parameters it needs. This is Shy Code. Best for unit testing. That is your ultimate metric.
Hope this helps.
Leo Bruzzaniti
PS. Those terms I've used are all from 'Pragmatic Programmer', I don't intend to sound at all like they are my invention.