Presents how to organize and package component-based software in a uniform (domain-independent) manner. This chapter also provides the fundamental C++ design rules that govern how to develop modular software hierarchically in terms of components, packages, and package groups. Save 35% off the list price* of the related book or multi-format eBook (EPUB + MOBI + PDF) with discount code ARTICLE.

* See informit.com/terms



2.1 The Big Picture

The way in which software is organized governs the degree to which we can leverage that software to solve current and new business problems quickly and effectively. By design, much of the code that we write for use by applications will reside in sharable libraries and not directly in any one application. Our goal, therefore, is to provide some top-level organizational structure — such as the one illustrated in Figure 2-1 — that allows us to partition our software into discrete physical units so as to facilitate finding, understanding, and potentially reusing available software solutions.1

FIGURE 2-1: Enterprise-level view of software organization

As Chapters 0 and 1 describe, most of what we do with respect to creating new library and application software involves components as the atomic units of design. But components alone, as depicted in Figure 2-2a, are too small to be effective in managing and maintaining software on a large scale. We will therefore want to aggregate logically related components having similar physical dependencies into a larger physical entity that we refer to as a package, which can be treated more effectively as a unit. These larger logically and physically cohesive entities can then, in turn, be further aggregated into a yet larger body of software, which we call a package group, comprising packages having similar physical dependencies2 that, taken as a whole, are suitable for independent release, as illustrated in Figure 2-2b.

FIGURE 2-2: Individual components do not scale up.

In addition, some of the software that we might need to use could be organized quite differently. For example, we may want to take advantage of certain third-party and open-source libraries, which might not be component-based. We might have our own legacy libraries to use that are also not component-based. These software libraries, of necessity, must come together at a level of aggregation larger than components, as depicted in Figure 2-3.

We generally think of a top-level unit of integration within a large system informally as a “library” whose interface typically consists of a collection of header files in a single directory (e.g., /usr/include ) and a single library archive (e.g., libc.a , libc.so ) depending on the target platform. We might uniquely refer to this particular architectural entity as a whole as “The C Library” although its internal structure (i.e., how logical content is partitioned among its .o files) is entirely organizational (i.e., not part of its specification or contract; see Volume II, section 5.2) and might vary from one vendor platform to another.