##Understand the components
Understand the components
Let's start with a fundamental assertion that, I hope, is already self-evident:
Smaller teams are more efficient, creative and productive than larger ones.
And a simple, but fundamentally important maxim:
To cook an elephant, break it into smaller pieces.
In programming terms, we do this by encapsulating, abstracting and modularizing, always striving to create coherent, easily understandable, functional and consistent interfaces between components. Each part of the elephant gets its own conceptual black box; once the internals of each black box are designed, coded, tested and accepted, nobody has to think about the box's insides anymore, unless a new requirement dictates a functional change.
This works at the people level as well. Because smaller teams are more efficient than larger teams, larger companies (especially matrix organizations) frequently have several smaller workgroups, each of which is responsible for a certain part of the software.
##Document the interactions
Document the interactions
As you've probably already figured out, the problem is not the black boxes, it is understanding the interactions between the black boxes. There are a number of techniques for dealing with this, all of which involve more time and resources:
- Class documentation
- Integration tests
- Architectural diagrams
- Data flow diagrams
And so forth. Of course, you have to have people who can read and understand this documentation and apply it at a high level. It must be available to the software developers, and kept up to date.
We're dreaming, right?
Where I work, we run a pretty lean shop. But we do our best to create these artifacts. They are, in fact, required elements of the overall software product.
##Divide and conquer
Divide and conquer
Basically, what you want is for your small teams (and your software baby elephant) to look more or less like this:

And your overall software team (and grown software elephant) to look something like this:

The real challenge is this: how do you maintain your information flow at a high level of quality and productivity? Within systems design, the way that is done is by carefully designing the communications between nodes, so that the interfaces, actors, objects and messages are well-defined, consistent, clear and understandable.
Remember, we're talking about black boxes here. We already understand the black boxes; the key is to understand the interactions that take place between the black boxes. A sensible architecture can mean the difference between well-organized and easily understandable software, and a big ball of mud.
And finally...
Be clear about what you want
If you have unclear or underspecified software requirements, it's not realistic to have a good understanding of the software. Requirements should be understandable in a way that the stakeholder can clearly understand when a feature is fully completed, and there are specific, identifiable and measurable metrics by which success can be declared.