36

I'm finding lots of 2-3k line files, and it doesn't really feel like they should be that big.

What is a good criteria to objectively call a source code file "too big"?, is there such thing as a maximum amount of lines a source code file should have?

  • Your peer tells you after reviewing the code. "You cannot determine this yourself because you know more as the author than the code says by itself. A computer cannot tell you, for the same reasons that it cannot tell if a painting is art or not. Hence, you need another human - capable of maintaining the software - to look at what you have written and give his or her opinion..." – gnat Nov 24 '12 at 14:22
  • Some compilers used to have weird limits on source code size: max line length or max number of lines. When compiler complains, this is an objective indicator that code is too big (or that it is time to upgrade). – mouviciel Nov 25 '12 at 11:17
  • 2
    Split as much as possible, but without breaking the integrity of files. Each file (or pair of header/source files) should always be a rounded whole, independent of the internal implementation of other files. If this means some files will be large because they implement something complex, so be it. – Ambroz Bizjak Nov 25 '12 at 11:25
  • Note that complexity is not just about numbers, but also about structure. For example, I'd like to state the python zen "flat is better than nested": a flat list of 100 cases is simpler than a hierarchy (you won't remember all 100 cases but you easily remember that there are 100 alternatives). And a "regular" hierarchy where branches have the same structure than their siblings are simpler than hierarchy with irregular sub-structure. – Juh_ May 31 '18 at 10:02
  • "Is that the source code?" "No, that's the makefile, The source code is in the trucks following behind". – mckenzm Apr 30 at 6:08
25

As an ideal model I use the following criteria (with a similar rationale to what Martin Beckett suggested, i.e. to think in terms of logical structure and not in terms of lines of code):

Rule 1

One class per file (in C++: one class -> one header and one implementation file).

Rule 2

Seven is considered the number of items that our brain can observe at the same time without getting confused. Above 7 we find it difficult to keep an overview of what we see. Therefore: each class should not have more than 7-10 methods. A class that has more than 10 method is probably too complex and you should try to split it. Splitting is a very effective method because every time you split a class you reduce the complexity of each individual class at least by a factor of 2.

Rule 3

A method body that does not fit in one or two screens is too big (I assume that a screen / editor window is about 50 lines). Ideally, you can see the whole method in one window. If this is not the case, you only need to scroll up and down a bit, without forgetting the part of the method that gets hidden. So, if you have to scroll more than one screen up or down to read the whole method body, your method is probably too big and you can easily lose the overview.

Again, splitting methods using private help methods can reduce method complexity very fast (at every split the complexity is at least halved). If you introduce too many private help methods you can consider creating a separate class to collect them (if you have more private methods than public ones, maybe a second class is hiding inside your main class).

Putting together these very rough estimates:

  • At most one class per source file.
  • At most 10 public method per class.
  • At most 10 private method per class.
  • At most 100 lines per method.

So a source file that is more than 2000 lines is probably too large and starting to be too messy.

This is really a very rough estimate and I do not follow these criteria systematically (especially because there is not always enough time to do proper refactoring). Also, as Martin Beckett suggested, there are situations in which a class is a large collection of methods and it does not make sense to split them in some artificial way just to make the class smaller.

Anyway, in my experience a file starts to get unreadable when one of the above parameters is not respected (e.g. a 300 line method body that spans six screens, or a source file with 5000 lines of code).

  • 1
    I would also strive for methods no more than 10 lines...helps with readability/understanding what the method is doing & reduces complexity that can easily happen in big methods... – Zack Macomber Sep 22 '16 at 17:02
  • 4
    Rule2 is absurd if you follow it to its conclusion. You should not have more than 7 files in a directory so you have to keep your files big so that you don't get confused between the tens or hundreds of files in your project. Similarly, a deeply nested directory structure is overly confusing so it's better to keep a few large files in one directory than scatter everything around. – hasen Oct 12 '17 at 6:09
  • 1
    I'm sorry this answer is based on wholly arbitrary metrics. The "7 items" is clearly bullshit, otherwise you wouldn't be able to use the alphabet. The size of object should be based on separation of concerns, single-responsibility, hight-cohesion-low-coupling and similar principles, not arbitrary numbers. – JacquesB Oct 12 '17 at 7:28
  • 1
    @JacquesB The 7 items is usually indicative of 7 pieces of unrelated information. If your brain can associate or group information, in a real sense it is 1 piece of information that can lead to more if you try to recall (in fact "alphabet" is a symbol, not all 26 letters). A better example would be trying to remember a 7 digit number told to you over the phone without having pen and paper available. Methods clearly aren't arbitrary numbers, but if those methods are relevant to what you're coding, you can expect after 7, you'll have to look for it before you can recall correctly. – Neil Oct 12 '17 at 8:55
  • 3
    @Neil: If the the methods in a class are random unrelated pieces of information, then you have bigger problems in your class design than the number of methods. – JacquesB Oct 12 '17 at 9:59
33

No - not in terms of lines of code. The driver should be logical grouping. There certainly shouldn't be multiple classes in one large file for example

If you had a class that legitmately had a few hundred methods (not impossible in say 3D modelling) it would be a lot less convenient to split that into arbitrary files. We used to have to do this when memory was scarcer and processors slower - and it was a pains, constantly searching for the function definition.

  • 2
    Wouldn't a class with hundreds of methods be a symptom of class envy, lack of cohesiveness, poor design, violation of single responsibility principle, etc. ? – Tulains Córdova Nov 24 '12 at 2:15
  • 2
    @user1598390: usually, but not always. – whatsisname Nov 24 '12 at 2:26
  • 4
    @user1598390 - common in say gis/3d modelling to have lots of operations you can perform, and then have them overloaded for 2d,3d,4d,3d+signal,then float/double/integer etc - templates help a little but for efficency lots of operations are often better than a pretty class heirarchy – Martin Beckett Nov 24 '12 at 3:01
  • 2
    @tp1 - and you use a small font so they don't take up as much space? – Martin Beckett Dec 3 '12 at 16:10
  • 2
    @tp1 Dude, I'm sorry, I really don't mean any disrespect, but I feel sorry for whoever works with you. If you have 1200 classes, use a directory convention, if you have too many directories, split them into independent modules/libraries. – dukeofgaming Dec 3 '12 at 19:39
8

When the code in it becomes unmaintainable. i.e: you can't tell just by watching the code if the method/class/function you're looking for (and have to edit/debug) is in there, or not, and if so, where it is.

Your IDE/Editor choice and features will influence this upper limit's actual quantification, though. Code folding, function/method listing, and lookup will postpone the moment this development scenario presents.

But when it does, it's time to split it.

2

Here is an alternative view: you are asking about how to limit file size. My opinion is that there are many factors that make large code files very problematic. Sometimes the code file is huge but its content are well clustered and extremely clean code, so that the size does not cause any significant problems. I have seen lots of files that are very readable despite the high LOC.

Instead of tapping into LOC metric, I would rather think about using the history data to understand how often the code gets broken in those large files. Usually the reason for that is that the developers do not have time to patience to check the relevant other places in the same file and make the change with "quick fix" mentality without enough understanding.

The bigger danger is the presence of copy-paste code. Copy-paste coding naturally also speeds up the LOC growth. I think eliminating copy-paste is even more imporant than keeping LOC below some magic number. In addition to pure copy-paste, there is also a second danger in the big files: overlapping functionality. The bigger the file is, the more likely you end up reimplementing some snippet that is already in some other section of the same file.

So, as long as bug fix ratio (ratio of bug fix commits to all commits) is low for the larger files, the situation is tolerable. Please try git log for it and skim through how many of the commits are related to errors. Or use a tool that can automatically analyze and visualize it, e.g. Softagram.

-1

Consider this Metaphor. When it comes to code length, I think we should consider the following:

The Cat in The Hat (50 pp.)

and

Lord of The Rings (1,178 pp.)

There is nothing wrong with Lord of the Rings. It's a fabulous book. The Cat in the Hat is also a great book. Both can be understood by a 5 year olds, but only one is better suited due to content.

To my point, writing code should make sense to a 5 year old whenever we can. Cyclomatic Complexity is an important concept that may developers should consider as they generate code. Utilizing and creating libraries to enhance functionality and code reusability as much as possible. This way our code can speak more volumes than what we see written.

Most of us are not writing assembly code. But the root of our code is assembly. Searching through 10000 lines assembly is harder than 10000 lines of python, if it is done correctly.

But some work requires writing 500 to 1000 lines. Our goal with code should be to write 300 lines of clean code.

As developers, we want to write "Lord of The Rings". Until we get a bug and wish we were writing "Cat in the Hat". Don't make coding a measure of ego. Just make things work in a simple fashion.

Developers don't want to document code, (I love documented code personally, I'm not that selfish). So don't write code that only you can understand/read. Write Cat in the Hat code.

We all know you are J.R.R. Tolken (in your head). Remember you will have nothing to prove with bug free code.

Another reason for the Metaphor.

Don't overkill the reader spread the wealth. If you work with a group of people and all of them have to change that same a large file, you are will probably putting yourself into git merge hell.

Everyone loves rebasing.

-> Said no one ever!

TL;DR Focus on readability. Spread your code and helper over multiple lines and files as much as you can. Don't throw 8 or 9 classes in a single file, It makes the code hard to read and harder to maintain. If you have a large condition code or loop, consider changing them to Lambdas if the language supports it. Utilities functions should be considered a great avenue to increase code readability. Avoid heavy nesting.

  • Not a downvoter, but your analogy is a bit lost on me. Are you saying it's better to spread your code over multiple lines, and have less words on each line? – Fodder Apr 11 at 23:51
  • Spread code and helper over multiple lines and files as much as you can. Focus on readability. Don't throw 8 or 9 classes in a single file. It makes the code hard to read and harder to maintain. If you have a large condition code or loops. Turn them into utilities. Avoid heavy nesting. Please let me know if this helps explain it. – GetBackerZ Apr 13 at 1:15
  • Perhaps you should edit that into your answer, as that would make it clearer what you mean. – Fodder Apr 14 at 22:06
  • I used the script for Jackie Brown as a yardstick for modular z/OS COBOL programs. You know, for cocktail party banter... – mckenzm Apr 30 at 6:11
  • "make sense to a 5 year old whenever we can." - for real world problems that pay the bills, this is rarely possible, and is aiming for the wrong thing – whatsisname May 22 at 23:06

protected by gnat Oct 12 '17 at 7:08

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.