For a model to be useful, we not only need to be able to abstract away presently-not-relevant subject matters, and use a language at an appropriate level of abstraction, but we should also try not to show everything at once. For example, combining a class diagram with communication diagrams to show both static structure and the dynamic behavior of customers and their accounts would quickly become too confusing for a viewer of the diagrams to understand. Consequently, we need multiple complementary and interrelated projections that, when taken together, form a complete model. (Note that we're using "projection" to mean a representation of some sort, and "model" to mean the underlying set of abstractions, classifications, behaviors, and so forth. In this manner, each diagram is a representation of some projection on a model.)
It's not unreasonable to treat subsets of models (or single diagrams, for that matter) as models in their own right, and to use mapping functions to map between them, as one might if one were to, for example, populate a communication diagram from function invocations and signal-sending actions on a statechart diagram. However, it simplifies the discussion to treat this as a special case, where the level of abstraction of the languages used in the two diagrams is the same.
This brings us to yet another form of abstraction: simply leaving stuff out. Some models may be plain incomplete at a given level of language abstraction. MDA is perfectly happy with this situation in general (so long as the missing elements are added eventually, of course). A typical situation where this occurs is in the addition of handcrafted code. There's nothing wrong in having MDA support handcrafted code, as long as you don't take it as an "out" but instead use it with care. As a rule, you should express everything you can in the model. We discuss how you should approach adding and maintaining handcrafted code to a model in Chapter 8.