There is an old saying that mathematicians only know three numbers: 0, 1 and ∞ (infinity).
There is some truth in this in computing too, as dealing with a single entity can be very different to dealing with a multiplicity of that entity. In JDK 1.5 speak: Am I using a
Thing or a
It is possible to build a system using single entities at each level of the system hierarchy. Imagine a system running on a single virtual machine composed of a single deployment unit containing a single package with a single class that has a single method which is a single line of code. It is possible to do this, but no one takes it to this extreme. (Although, the thinlet Java GUI toolkit comes close, being a single class of 6000-plus lines, an example of the blob anti-pattern) The usual guidance for getting the right system decomposition is to follow the Unix philosophy of Do one thing, do it well at all levels. Following this advice, you split things when they try to do too much.
This is easy enough to understand and apply at the level of individual lines of code, but harder to realize as we move up the levels of the hierarchy.
What often happens is that at the higher levels we just have single instances, which is fine when the system starts out but over time grows to be an unwieldy monolith. The problem is by the time you recognise that it really is time to split up the system, it is actually quite difficult to do so since it is so complicated! It would be easier to modularise early. Knowing that you system can function with (say) two EARs tells you how you can expand it to run from three in the future. But imagine you had just a large single EAR. When you came to split it, as well as solving the usual problem of where to split the code, you have to work out how to split it - that is, how to make the system run from two deployment units as opposed to one. The combination of these problems can be enough to make any reasonable programmer balk, and carry on bloating the single EAR... I know this has happened to me.
One of the striking things about Jini is the way it encourages you to embrace multiplicity at the high end of the hierarchy from the outset. This is for a simple reason: a Jini system is a collection of orchestrated services running in many VMs. Perhaps we can learn some lessons from Jini about building more modular systems. This is not a new thought, the pioneer computer scientist Grace Hopper made a similar point in the mid-twentieth century:
In pioneer days they used oxen for heavy pulling, and when one ox couldn't budge a log, they didn't try to grow a larger ox. We shouldn't be trying for bigger computers, but for more systems of computers.