Smaller classes seem to make a lot of developers uncomfortable.
It seems that the idea of jumping between classes in order to get the whole picture is undesirable, and that instead they would prefer a gigantic class with 20-30 methods, over 5-10 classes with 2-3 methods.
What is it about using smaller classes that make people uncomfortable? Does not smaller classes with clear purposes make the code more maintainable? Does it not make it more testable? Does it not make the code short, readable, and concise?
Chicken vs Dinosaurs
Would you rather fight 100 small dinosaurs, or a giant chicken?
We have all had this discussion at some point. Perhaps the giant chicken was a giant horse. Or perhaps the dinosaurs were tiny horses, I don't know.
Regardless, I would rather choose to face 100 small dinosaurs. A single attack from the chicken would probably critically injure or terminate us, but with the 100 small dinosaurs we would have a fighting chance. You cannot outrun a giant chicken, after all!
I believe the same applies to classes!
We should split the big classes into smaller dinosaur classes, so that we can tackle one small problem at a time. Let each little class get their time to shine when we get change requests, or when adding new functionality.
Advantages with Smaller Classes
These three key points are some of the most important goals for us, the developers, to follow.
Maintainability is provided by separating certain behavior out of the larger classes; into a class whose prime responsibility is to service that behavior to other class(es). When we need to make a change, we only need to change it there, and only once.
Flexibility comes from being able to use existing work. We can extend the separated class to override certain functionality, or perhaps build a wrapper class that takes in the class as a parameter. Perhaps the proper course of action would be to convert the class we are working on into an interface, and work with that.
Readability is shown by reading the class. Having a concise class with a single behavior/purpose allows us to look at that class, and read what that class is doing. It allows us to more easily read the code, by not polluting your classes with logic of certain behavior that really belongs in its own class.
Working with big classes is like fighting a giant chicken. Messy, and difficult to work with.
There seem to be an ongoing trend that many of us (developers) shy away from splitting up potentially big classes into smaller classes. Worse yet, there may be circumstances when we simply keep adding more and more into the same class.
The "best" and common argument I've heard for having larger classes, is having access to all the code in one place. You can easily find all the code related to the class, at least in the project tree. Because you are already there.
However, this is also likely to be a most unfortunate outcome. This kind of thinking breeds further technical debt and complexity into our code. Making the junior developers lose sleep and hair over it. Why? Because you would have to become familiar with the entire class in order to put together what is going on. If you had separated responsibilities into smaller classes, you would almost instantaneous recognize the behavior of the class you are in.
Unfortunately, the developers with a few years under their belt that are already familiar with the code, seem to be the biggest opponents of change. After all, they are already familiar with the code. They have overcome any maintainability and readability issues by spending the time developing and maintaining the mess. If someone were to clean up the code, they would have to re-familiarize themselves, and that can unfortunately be uncomfortable.
Facing your Fears
How would we go about to make change?
Dedicate a portion of your time refactoring and cleaning up the code you are working on! Make sure good tests are in place to protect you from making mistakes, and don't you go overboard by redesigning the entire system without the cooperation of your team architect. After all, your job is to make sure the code is maintainable, readable and flexible to change.
Test Driven Development is a good strategy to allow further change while reducing risk considerably
If you are unable to dedicate extra time for technical debt, for whatever reasons, you- together with the developers in your team would greatly benefit from adding additional time to your task estimations.
You are responsible for the code you write, and making sure you write code with quality is part of your job as a professional developer.
Tips for further Study
Writing clean code is not easy, and the road towards achieving it is long. It is very unlikely you will ever get there without taking your time to study.
Take your time to read, learn, and to figure out how to improve your own code.
To get started on this, I would highly recommend getting the book "Clean Code" by Robert C. Martin (Uncle Bob).