With the latest additions to our dependency injection framework (annotations in spring), the marginal cost of creating DI-managed components seems to have hit some critical new
Are you stressing the, "Grouping," or the, "Classes?"
If you're asking why are we grouping things, then I'd second Medelt's, "Maintainability," though I'd rephrase it as, "To reduce the potential cost of ripple effects."
Consider, for a moment, not the actual coupling between your components (classes, files, whatever they may be) but the potential coupling, that is, the maximum possible number of source code dependencies between those components.
There is a theorem which shows that, given a chain of components a - b - c - d - e, such that a depends on b, etc., the probability that changing e will then change the c component cannot be greater than the possibility that changing e will then change d. And in real software systems, the probability that changing e will affect c is usually less than the probability that changing e will affect d.
Of course, you might say, that's obvious. But we can make it even more obvious. In this example, d has a direct dependency on e, and c has an indirect (via d) dependency on e. Thus we can say that, statistically, a system formed predominantly of direct dependencies will suffer from a greater ripple effect than a system formed predominantly from indirect dependencies.
Given that, in the real world, each ripple effect costs money, we can say that the cost of ripple effect of an update to system formed predominantly of direct dependencies will be higher than the cost of ripple effect of an update to system formed predominantly of indirect dependencies.
Now, back to potential coupling. It's possible to show that, within an absolute encapsulation context (such as Java or C#, where recursive encapsulation is not widely employed) all components are potentially connected to one another via either a direct dependency or an indirect dependency with a single, intermediate component. Statistically, a system which minimises the direct potential coupling between its components minimises the potential cost of ripple effect due to any update.
And how do we achieve this distinction between direct and indirect potential coupling (as if we haven't already let the cat out of the bag)? With encapsulation.
Encapsulation is the property that the information contained in a modelled entity is accessible only through interactions at the interfaces supported by that modelled entity. The information (which can be data or behavior) which is not accessible through these interfaces is called, "Information hidden." By information-hiding behavior within a component, we guarantee that it can only be accessed indirectly (via the interfaces) by external components.
This necessarily requires some sort of grouping container in which some sort of finer-grained functionality can be information-hidden.
This is why we are, "Grouping," things.
As to why we're using classes to group things:
A) Classes provide a language-supported mechanism for encapsulation.
B) We're not just using classes: we're also using namespaces/packages for encapsulation.
Regards,
Ed.