I recognize that some classes come in all sizes. But is there a guideline that people use for when they start thinking "This object is too big, should I break it into smaller pieces"?
Maybe what I am asking here can't be answered in a completely general way. I have this feeling that an object is an abstract entity that can be understood in a single thought. A class is an object. Therefor a class is something that you should be able to keep in you head conceptually for at least as long as you are actively trying to expand/maintain it. That has worked well for me in the past, but I am struggling on my current project.
I am working on a project with maybe 60 or so classes (currently). I have one class that doesn't seem to fulfill the "all in your head" rule. If I had to call this class an object I would say it is the "flow control center" of my application. It runs in its own thread; sets up the initial GUI, connects requests from the current GUI to appropriate behavior; monitors a background task queue; organizes and/or prioritizes tasks, and spools off background threads to handle tasks that might otherwise tie up the task queue monitor for too long. It also has a growing "logic" section that makes decisions about application's final output to the remote server. At the moment this class is (only) 2000 lines long, and the logic section is just getting started. But even at just 2000 lines this "control center" class is already cumbersome dig through in an editor, and getting it all in my head at once is challenging. At the rate things are growing, this class could have a 150 methods before I am done. It will be unwieldy at that point. Moreover, I don't want the guy who takes my place to be confronted with 4000 lines of code in order to figure out how to change the permissions of how files are downloaded. Maybe that means I am NOT writing it correctly! And thus my question, "How big, is too big?". is the "in your head all at once" rule a valid one? Can someone point me to something that will help me to learn how to break down these jumbo classes into smaller ones?
I fear that what you are doing there is to use the God object antipattern. In fact that Wikipedia article is a lot too close to what you described.
I have this feeling that an object is an abstract entity that can be understood in a single thought.
Yes, or to put it another way, you should be able to describe succinctly what it's for. If your description contains the word "and" or -- worse -- contains a list, then you're right, it should be broken up.
For a start I would guess that you could split off the part which deals with tasks from the part which deals with talking to the GUI. And I guess (with a lot less certainty) that your inflationary "logic" section might be tamed if you applied (say) the Strategy pattern to break clumps of similar code into separate classes.
Paul Clapham wrote:I fear that what you are doing there is to use the God object antipattern.
That article describes exactly what is going on here!
One quote from aforementioned wikipedia article struck me as particularly convincing.
A God object is the object-oriented analogue of failing to use subroutines in procedural programming languages
And that is precisely what I was thinking about when I made my original post. I just new this was wrong, but couldn't quite put a name to it. The names of things rarely hold any real significance; but somehow I feel that knowing that other people have seen/dealt with this before me gives me some cause for reassurance. My instincts on this were right. I was writing this incorrectly.
I will review the strategy pattern (and a few others) and see of something jumps out at me.
At work we have to deal on a daily basis with these monster classes. Relics from the past written by programmers long since gone. Understanding, maintaining, and especially testing and refactoring them is HARD WORK. We curse the people who made them daily. Just FYI
What the hell is going on in this class? It's like a warzone
If I ever meet the one who wrote this I will punch him in the face
I strive to never be that kind of programmer.
I spend half my time fixing mistakes made by the programmers that came before me. My predecessors get all the credit for making a project, and I get saddled thankless task with "making it work". If I didn't like do this so much I would have given up years ago in frustration.
I recall reading somewhere that a class generally shouldn't have more than around 2000 lines of code. That's when it becomes a maintenance nightmare. In the same line of thinking - my manager firmly that a method should not be longer than one screen (i.e. you should be able to see the entire method on-screen).
If I were you, I would try to divide your methods into groups, and when you find a bunch of methods that you can mentally put in a "group", move those methods to a new class.
"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man." - George Bernard Shaw