Ask HN: How do you manage your codebase once it gets large?
(This is my first "real" project using Rails, so I have no previous experience on this question :P )
(This is my first "real" project using Rails, so I have no previous experience on this question :P )
My suggestions:
1) Refactor like it is going out of style. Rails classes (particularly controllers and models in my experience) have a tendency to accumulate cruft over time. Periodically evaluate whether something should be broken into two classes, or at least two files. Mixins and require are your friend here. (Breaking a controller into two changes URLs by default. I think letting Rails assign publicly visible URLs is a mistake, but most people do it. Consider carefully whether you can accept URLs changing as a result of code changes.)
2) Encourage internal code reuse, and better separation of responsibilities, by breaking things into plugins when appropriate. I extracted code from my own classes to make A/Bingo for example. It keeps my own classes readable and makes it much easier to publish and reuse A/Bingo.
3) Coding conventions are your friend. Since the IDE lacks a reliable jump-to-definition-of-this-function feature, I tend to try to put predictable things in predictable places. For example, model classes always have a consistent ordering of filters, validations, and associations at the top of the file prior to business logic. (Those could be externalized if they got realllly messy, via the magic of require.)
4) Put partials into thematically coherent subdirectories. This saves you from having to find the right form partial from a directory with 20 views and 50 partials.
Plus, you end up in a position where you can give back to the community, which is nice.
My other suggestion, regarding point (3) would be to not rely on the IDE to heklp you navigate the code. If it's your code you should really have laid out the classes and source files so things are in a logical (to you) order and easy to find. (I'm currently working on a 12 kline project and my IDE consists of multiple kwrite windows plus the command line -- I find this enough to navigate the code).
Also, another good thing to keep in mind is to avoid partialitis. Many people tend to start making partials for every single widget on the page. Don't do that. Only use partials when it DRYs up your code, and sometimes, it's better to encapsulate UI elements into helpers. Also, partial rendering can get expensive.
The worst is when you're faced with a directory of dozens of partials that are ambiguously named.
We follow a simple MVC principle, C++ side is model, JNI-glue is control, and Java is view. Then, individual pieces are broken into functional modules and there is documentation on slides (flowcharts) on how these functional components interact.
You should be able to let go and trust fellow developers. I don't know all of the code; There are four others who have their own pieces of functional modules that they are responsible for. I trust their judgement/decisions on their modules just like they trust mine-- we still question which is important.
Rest of it sort of fall into place as we progress. Hope this helps.
You want to make changes that do as little damage as possible. By structuring your project so that independent functions are really independent, you can think about them independently. Providing interfaces to your own code also helps there, you can ignore one part of the code and just use its functionality, and only have to keep the interface in your head. Also, notes-to-self often help provide context and memory cues to reload something you've forgotten. Either way, you should be using source control. That way you can look at the changelog for a file and reconstruct what you did with it, again helping you recall structure.
The most used projects, used daily by our clients are in the 2000-4000 range, the smaller ones are supporting tools and the two massive ones are that way because the business rules are completely insane. Also they are quite old and could probably be trimmed down quite a bit.
Some of the more actively developed code has been trimmed down through constant development, the two monsters do not get touched too often.
Actually I'm quite surprised has to how small our core applications are, I would have guessed more in the 8000-12000 LOC. But then Ruby tends to be rather concise.
What sort of numbers are you seeing?
It's not impossible to manage yet, but I'm beginning to notice that it's getting harder. I think doing some refactoring and general cleanup will help with that.
Then, I would look into dividing up the code base a bit. Usually once you get to a certain size you'll be able to identify useful bits and pieces that could be extracted as standalone libraries. This will also render these more generic parts of your code ready to reuse.
You might also find it useful to divide the application-specific parts into layers and ensure lower layers don't depend on higher ones. These types of divisions allow you to consider lower layers independently. And when you're hunting for something, you should have a feel for which layer it is in first, which narrows your search scope.
For example with the language/VM I've got built for doing some DSL work, I've got folders for the garbage collector (src/gc), the compiler (src/compiler), the runtime (src/runtime) and so on. I'm not entirely familiar with doing any sort of large-scale ruby development so I don't know how much that helps you (most of my ruby code are small 100-200 line all inclusive scripts).
Hope that helps.
Another crucial aspect is unit tests - as long as you know the project well, you can go in and make a change relatively easily, as long as you know that a system of unit tests will catch any unintended side-effects.
http://railsconfeurope.blip.tv/file/1555560/
Breaking pieces out into modules (and even further into plugins) can help keep it manageable.
Same presentation.
For Java code, Eclipse performs similar functions.