by Colin Miller
I'm not a manager. I'm not even a big fan of huge corporations where it's difficult to change the direction of the projects if you're a smaller part of a whole. I'm also not a fan of projects whose code gets carried away by constant additions to a select few classes that lead to bloated spaghetti code.
Have you ever worked on a project where there was a single class that was over 2000 lines long? I've worked on code bases with class files that are over 20k lines. That's not a very manageable and maintainable situation. Ideally, you should be able to roughly describe a classes purpose in 2-3 sentences. The amount of purpose for a 20k line class is too vast. Navigating such a file is a tremendous hassle.
In startup land, new companies are often formed from small teams of 1-10 people. If you start with a team of 3, and more work piles on, you eventually need to hire more people. An individual who was the founder in a startup might take on the role of designer, developer, QA, Product Manager, Marketer, Sales, and HR. For a 2 person team, this might be acceptable. But how about when the company grows? What roles should that founder take when there are 500 employees? Probably not all of the ones she took on previously.
As a company grows, those early individuals need to delegate some of their previous work to new employees and focus on a more narrow subset. If someone founds a company that gets larger, they probably shouldn't be doing development, design, managing other people, meeting with investors, and selling the product. There are other people who can take on some of those roles so that the founder can focus on growth and management. She can meet with investors and deal with other management, but have other people doing design and development and perhaps even sales.
There are several ways that a company can grow and design its organizational infrastructure. Some take a hierarchy view of things where there's a pyramid starting from the CEO and branching down from upper executives to upper management to middle management to local team leads to individual contributors. Others take the a flatter approach where each person takes a piece of work and forms self-organizing teams temporarily around projects without as many layers of management (Valve Software is famous for this style).
That's only two examples, there are dozens of other ways to organize a company. The important part about it is to make sure that each employee can contribute their maximum amount and that no one is overloaded with work. An overloaded worker can block others, make bad decisions, and will probably get stressed and burned out faster causing even further problems.
What does all of this management stuff have to do with coding? I feel that there's some similarities in how an organization grows over time and how a code-base grows over time. If some initial classes take on too many responsibilities and continue to be added to as development goes without any refactoring, you'll end up with those 20k line class files. This becomes a nightmare of maintenance! Why not get some new bodies (classes) in there to help out and break the problems down into smaller more manageable sections?
Sometimes an application will have a single entry point for a variety of features. Maybe it's an Android activity or Fragment. Maybe it's a particular HTTP endpoint that accepts complex queries. In the beginning, the APIs for these, and the amount of work they were asked to do, was probably pretty reasonable. A single class was all that it took to handle the work. As the usages grew, more and more was added to the class. Suddenly you're in the same situation as the Founder who's also a developer, designer, marketer.. etc. When you start to see this in your code, you need to delegate responsibilities to other classes. The initial entry point class becomes a controller which merely passes along the actual work to other objects who have that area as their expertise. Even those might be controllers that pass down further, just like a management chain might.
Another way of subdividing your code would be to break up those large end-points or APIs into smaller ones that smaller classes can handle. Rather than a single complicated Android fragment, maybe you can separate out sections into seperate fragments. Or have different classes handle different endpoints rather than one master controller.
The main argument I would make is that as your project grows, the number of classes/files in your project should grow, but your have class/file length should remain about the same. This will keep you sane and be a lot easier to manage and control in the future.