When you are developing, when can you determine if you have a lot of unnecessary classes in your application? Is there a certain limit on how many classes you should have?
Taking 12-15 credits is considered “full-time” in college lingo. That amounts to 4-5 classes, and for young students, that course load is really heavy (let's be honest, it's heavy for MOST students of any age).
Is there a certain limit on how many classes you should have? DEFINITELY YES - that is probably the single, most difficult part of any OOP project : defining the minimal set of classes to get your job done.
The four principles of object-oriented programming are encapsulation, abstraction, inheritance, and polymorphism. These words may sound scary for a junior developer.
There really isn't such a thing as "too many classes." What can be a problem is "too many classes doing the same thing."
If you feel that you have too many classes in your codebase, a good way to audit that would be to add some new requirements. Anything that forces you to make some changes to the code. (In a separate branch of the source control, of course.) How difficult is it to make those changes? Does a relatively simple change require that you modify tons and tons of classes? If that's the case then there's a very good chance that you do have too many, but the problem isn't the number itself.
It's primarily a matter of personal preference in many cases. There's often a trade-off between code re-use and code de-coupling. By separating out every concern possible and having lots of small classes, you de-couple everything from everything else. However, you often find that you have to repeat code in such cases because a lot of code might be doing "the same thing" but for a slightly different reason.
On the other hand, if you insist on never repeating anything in the code, then while you get fewer classes you also often end up with more coupling because a single class will have multiple responsibilities to any code which requires similar functionality.
The bottom line in most cases is resistance to change. Coupling vs. re-use is something people can argue about at length, but software rigidity is where the argument turns into actual effort (money). Test how difficult it is to make changes to the code. Then try re-arranging your classes/logic in a manner that you think would be more accepting of change and test it again. Was there a significant improvement?
Generally alot of classes means you are likely to have solved your problems very generally. This is usually good since it means you hopefully will have an easier time changing behaviours when you eventually need to.
When developing smaller projects sometimes it can be better to be more specific (i.e. less general) to achieve things faster this could lead to less classes, but might be harder to change when the need appears.
As long as the classes are well ordered and have a well defined purpose it should not be a problem to have many classes.
What can how ever be a problem is if classes are tightly coupled or if the responsibility of some classes are not well defined. More info about coupling can be found here.
Another problem that can occour is mentioned in the comment below. If a lot of your classes have similar code you have a Duplication problem. This usually leads to a decreased maintainability in the system becuse if a change is needed in the duplicated code you have to make changes multiple times. This is usually solved by inheritance.
Kent Beck answers your question. Jeff Langr in the book 'Clean Code A Handbook of Agile Software Craftsmanship' discusses the four design rules as specified by Kent Beck.
(in order of importance)
Kent suggests that a pragmatic approach be adopted to keep the class and method count low. He gives the example of adhearing to dogmatic rules such as all classes should have interfaces. Usually yes but sometimes there are situations where this might not be necessary. However, this rule is the lowest priority of the four rules of simple design.
(note, this is Kent Becks opinion, not so much mine!)
In a project I'm currently working on I definitely think we're using too many classes - or at least, too many objects/instances.
We built a CMS based on PHP/MySQL where every record and field in the database is represented as an object in PHP. This can result in tens of thousands of instances at the same time and we're continually running into performance issues/running out of memory, etc.
This may of course not be an issue in other programming languages or with other requirements, but performance is, in my opinion, something to consider as well.
As many others have suggested, "it depends..."
Usually it depends on a combination of your methods, your goals and the preferences and abilities of your team members. If you are very stringent about unit tests, you probably end up with a lot of small, general classes and dependency injection. This also means that it's very hard for the individual team member to see the concrete whole you are building from all the parts that are so very, very generic.
Personally I prefer to think in terms of an API built on two levels: A lower level made of generic, independent parts and a high level where I use a couple of facades, directors etc. to present something concrete and useful to the other coders. This is much like the design of the iOS libraries IMHO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With